Les anciens DBA racontent qu'Oracle fournit un "SQL*Loader" sans aucun "SQL*Unloader" parce que Larry Ellison ne voulait pas que ses clients déménagent. Cela a changé :il existe un moyen simple d'exporter vers CSV avec un simple set sqlformat csv
dans SQLcl. Suivez le blog de Jeff Smith pour en savoir plus.
Voici un exemple. Je voulais déplacer des exemples de données d'Oracle vers YugabyteDB pour comparer la taille. J'ai une base de données autonome toujours gratuite, qui inclut l'exemple de schéma SSB. Il existe une table LINEORDER qui fait quelques centaines de Go. J'obtiendrai le DDL avec dbms_metadata
. Le seul changement que j'avais à faire était sub(" NUMBER,"," NUMERIC,")
et j'ai désactivé les contraintes et les clauses de classement.
Bien sûr, il existe des outils professionnels pour convertir un schéma Oracle en PostgreSQL. Le bon vieux ora2pg, ou AWS SCT qui est aussi formidable pour évaluer le niveau de changements requis par une migration. Mais pour quelque chose de rapide, je suis bon avec awk
😉
Ensuite, l'exportation est facile avec set sqlformat csv
et les quelques paramètres pour ne sortir que des données comme feedback off pagesize 0 long 999999999 verify off
. Je dirige tout ça vers awk
qui construit le \copy
commande qui prend ces lignes CSV telles quelles. J'aime faire de petites étapes, puis créer des commandes COPY de 10 000 lignes avec (NR-data)%10000
, data
défini au début de la commande COPY. Les envoyer en parallèle serait facile, mais je n'en ai peut-être pas besoin car YugabyteDB est multithread.
Voici le script que j'utilise - J'ai mon portefeuille de base de données autonome dans TNS_ADMIN, SQLcl installé chez moi (un ARM de niveau gratuit Oracle sur lequel j'exécute également mon laboratoire YugabyteDB).
{
TNS_ADMIN=/home/opc/wallet_oci_fra ~/sqlcl/bin/sql -s demo/",,P455w0rd,,"@o21c_tp @ /dev/stdin SSB LINEORDER <<SQL
set feedback off pagesize 0 long 999999999 verify off
whenever sqlerror exit failure
begin
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'SEGMENT_ATTRIBUTES', false);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'STORAGE', false);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'CONSTRAINTS', false);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'REF_CONSTRAINTS', false);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'SQLTERMINATOR', true);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'COLLATION_CLAUSE', 'NEVER');
end;
/
set sqlformat default
select dbms_metadata.get_ddl('TABLE','&2','&1') from dual ;
set sqlformat csv
select * from "&1"."&2" ;
SQL
} | awk '
/^ *CREATE TABLE /{
table=$0 ; sub(/^ *CREATE TABLE/,"",table)
print "drop table if exists "table";"
schema=table ; sub(/\"[.]\".*/,"\"",schema)
print "create schema if not exists "schema";"
}
/^"/{
data=NR-1
print "\\copy "table" from stdin with csv header"
}
data<1{
sub(" NUMBER,"," numeric,")
}
{print}
data>0 && (NR-data)%1000000==0{
print "\\."
print "\\copy "table" from stdin with csv"
}
END{
print "\\."
}
'
La sortie peut être directement redirigée vers psql
😎
Voici mon écran au démarrage du chargement :
C'est un laboratoire, mesurer le temps écoulé n'a pas de sens, mais j'ai regardé rows_inserted
statistiques pour vérifier que tout est distribué aux 3 nœuds de ma base de données SQL distribuée. Même avec une seule session client, la charge est répartie sur tout le cluster.
Cela fonctionne de la même manière pour PostgreSQL car il s'agit de la même API :YugabyteDB utilise PostgreSQL en plus du stockage distribué.
Tous les composants de ce test sont gratuits et faciles à utiliser :
- La VM est sur Oracle Cloud Free tier (ARM), la base de données Oracle est une base de données autonome gratuite 👉 https://www.oracle.com/cloud/free/
- PostgreSQL est open source et gratuit 👉 https://www.postgresql.org
- YugabyteDB est open source et gratuit 👉 https://www.yugabyte.com