Gamla DBA:er har berättelser om att Oracle tillhandahåller en "SQL*Loader" utan någon "SQL*Unloader" eftersom Larry Ellison inte ville att hans kunder skulle flytta ut. Detta har ändrats:det finns ett enkelt sätt att exportera till CSV med en enkel set sqlformat csv
i SQLcl. Följ Jeff Smiths blogg för att veta mer om det.
Här är ett exempel. Jag ville flytta lite exempeldata från Oracle till YugabyteDB för att jämföra storleken. Jag har en alltid gratis Automonous Database, som inkluderar SSB-exempelschemat. Det finns en LINEORDER-tabell som är några hundra GB. Jag skaffar DDL med dbms_metadata
. Den enda ändring jag behövde göra var sub(" NUMBER,"," NUMERIC,")
och jag inaktiverade begränsningar och sammanställningsklausuler.
Naturligtvis finns det professionella verktyg för att konvertera ett Oracle-schema till PostgreSQL. Den gamla goda ora2pg, eller AWS SCT som också är bra för att bedöma nivån av förändringar som krävs av en migrering. Men för något snabbt, jag är bra med awk
😉
Sedan är exporten enkel med set sqlformat csv
och de få inställningarna för att endast mata ut data som feedback off pagesize 0 long 999999999 verify off
. Jag skickar allt det till awk
som bygger \copy
kommando som tar dessa CSV-rader som de är. Jag gillar att göra små steg och sedan bygga 10000 rader COPY-kommandon med (NR-data)%10000
, data
ställs in i början av COPY-kommandot. Att skicka dem parallellt skulle vara lätt, men jag kanske inte behöver det eftersom YugabyteDB är flertrådad.
Här är skriptet jag använder - jag har min Autonomous Database-plånbok i TNS_ADMIN, SQLcl installerad i mitt hem (en Oracle free tier ARM som jag också kör mitt YugabyteDB-labb på).
{
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 "\\."
}
'
Utdata kan skickas direkt till psql
😎
Här är min skärm när jag startar laddningen:
Det är ett labb, det är meningslöst att mäta förfluten tid, men jag tittade på rows_inserted
statistik för att verifiera att allt distribueras till de tre noderna i min distribuerade SQL-databas. Även med en enda klientsession fördelas belastningen på hela klustret.
Detta fungerar på samma sätt för PostgreSQL eftersom det är samma API:YugabyteDB använder PostgreSQL ovanpå den distribuerade lagringen.
Alla komponenter i detta test är gratis och lätta att använda:
- VM är på Oracle Cloud Free Tier (ARM), Oracle Database är en gratis autonom databas 👉 https://www.oracle.com/cloud/free/
- PostgreSQL är öppen källkod och gratis 👉 https://www.postgresql.org
- YugabyteDB är öppen källkod och gratis 👉 https://www.yugabyte.com