Oracle
 sql >> Database >  >> RDS >> Oracle

SQLcl per trasferire dati da Oracle a PostgreSQL o YugabyteDB 🅾🐘🚀

I vecchi DBA hanno storie su Oracle che fornisce un "SQL*Loader" senza alcun "SQL*Unloader" perché Larry Ellison non voleva che i suoi clienti si trasferissero. Questo è cambiato:c'è un modo semplice per esportare in CSV con un semplice set sqlformat csv in SQLcl. Segui il blog di Jeff Smith per saperne di più.

Ecco un esempio. Volevo spostare alcuni dati di esempio da Oracle a YugabyteDB per confrontare le dimensioni. Ho un database autonomo sempre gratuito, che include lo schema di esempio SSB. C'è una tabella LINEORDER che è di poche centinaia di GB. Otterrò il DDL con dbms_metadata . L'unica modifica che dovevo fare era sub(" NUMBER,"," NUMERIC,") e ho disabilitato i vincoli e le clausole di confronto.

Naturalmente, ci sono strumenti professionali per convertire uno schema Oracle in PostgreSQL. Il buon vecchio ora2pg, o AWS SCT, ottimo anche per valutare il livello di modifiche richieste da una migrazione. Ma per qualcosa di veloce, sono bravo con awk 😉

Quindi l'esportazione è facile con set sqlformat csv e le poche impostazioni per generare solo dati come feedback off pagesize 0 long 999999999 verify off . Convoglio tutto questo a awk che costruisce il \copy comando che accetta queste righe CSV così come sono. Mi piace fare piccoli passi e poi creare 10000 righe COPY comandi con (NR-data)%10000 , data impostato all'inizio del comando COPY. Inviarli in parallelo sarebbe facile, ma potrei non averne bisogno perché YugabyteDB è multithread.

Ecco lo script che uso:ho il mio portafoglio di database autonomo in TNS_ADMIN, SQLcl installato a casa mia (un ARM di livello gratuito Oracle su cui eseguo anche il mio laboratorio 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 "\\."
}
'

L'output può essere inviato direttamente a psql 😎

Ecco la mia schermata all'avvio del caricamento:

È un laboratorio, misurare il tempo trascorso non ha senso, ma ho guardato rows_inserted statistiche per verificare che tutto sia distribuito ai 3 nodi del mio database SQL distribuito. Anche con una singola sessione client, il carico viene distribuito su tutto il cluster.

Funziona allo stesso modo per PostgreSQL perché è la stessa API:YugabyteDB usa PostgreSQL in cima allo storage distribuito.

Tutti i componenti di questo test sono gratuiti e facili da usare:

  • La VM è su Oracle Cloud Free tier (ARM), Oracle Database è un database autonomo gratuito 👉 https://www.oracle.com/cloud/free/
  • PostgreSQL è open source e gratuito 👉 https://www.postgresql.org
  • YugabyteDB è open source e gratuito 👉 https://www.yugabyte.com