Oude DBA's hebben verhalen over Oracle die een "SQL*Loader" leverde zonder enige "SQL*Unloader" omdat Larry Ellison niet wilde dat zijn klanten zouden verhuizen. Dit is veranderd:er is een gemakkelijke manier om naar CSV te exporteren met een eenvoudige set sqlformat csv
in SQLcl. Volg de blog van Jeff Smith om er meer over te weten.
Hier is een voorbeeld. Ik wilde wat voorbeeldgegevens van Oracle naar YugabyteDB verplaatsen om de grootte te vergelijken. Ik heb een altijd gratis Automonous Database, die het SSB-voorbeeldschema bevat. Er is een LINEORDER-tabel van enkele honderden GB. Ik krijg de DDL met dbms_metadata
. De enige wijziging die ik moest doen was sub(" NUMBER,"," NUMERIC,")
en ik heb beperkingen en collatieclausules uitgeschakeld.
Natuurlijk zijn er professionele tools om een Oracle-schema om te zetten naar PostgreSQL. De goede oude ora2pg, of AWS SCT, die ook geweldig is om het niveau van veranderingen te beoordelen dat nodig is voor een migratie. Maar voor iets snels ben ik goed met awk
Dan is de export eenvoudig met set sqlformat csv
en de weinige instellingen om alleen gegevens uit te voeren zoals feedback off pagesize 0 long 999999999 verify off
. Ik pijp dat allemaal naar awk
die de \copy
. bouwt commando dat deze CSV-regels neemt zoals ze zijn. Ik doe graag kleine stapjes en bouw dan 10000 regels COPY-commando's met (NR-data)%10000
, data
wordt ingesteld aan het begin van het COPY-commando. Ze parallel verzenden zou gemakkelijk zijn, maar ik heb het misschien niet nodig omdat YugabyteDB multithreaded is.
Hier is het script dat ik gebruik - ik heb mijn Autonomous Database-portemonnee in TNS_ADMIN, SQLcl bij mij thuis geïnstalleerd (een Oracle gratis tier ARM waarop ik ook mijn YugabyteDB-lab draai).
{
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 "\\."
}
'
De uitvoer kan direct worden doorgesluisd naar psql
Hier is mijn scherm bij het starten van het laden:
Het is een lab, het meten van verstreken tijd heeft geen zin, maar ik heb gekeken naar rows_inserted
statistieken om te controleren of alles wordt gedistribueerd naar de 3 knooppunten van mijn gedistribueerde SQL-database. Zelfs met een enkele clientsessie wordt de belasting over het hele cluster verdeeld.
Dit werkt hetzelfde voor PostgreSQL omdat het dezelfde API is:YugabyteDB gebruikt PostgreSQL bovenop de gedistribueerde opslag.
Alle componenten in deze test zijn gratis en gemakkelijk te gebruiken:
- De VM bevindt zich op Oracle Cloud Free tier (ARM), The Oracle Database is een gratis autonome database 👉 https://www.oracle.com/cloud/free/
- PostgreSQL is open source en gratis 👉 https://www.postgresql.org
- YugabyteDB is open source en gratis 👉 https://www.yugabyte.com