Starzy administratorzy baz danych opowiadają, że Oracle dostarcza „SQL*Loader” bez żadnego „SQL*Unloader”, ponieważ Larry Ellison nie chciał, aby jego klienci się wyprowadzali. To się zmieniło:istnieje łatwy sposób na eksport do CSV za pomocą prostego set sqlformat csv
w SQLcl. Śledź blog Jeffa Smitha, aby dowiedzieć się więcej na ten temat.
Oto przykład. Chciałem przenieść niektóre przykładowe dane z Oracle do YugabyteDB, aby porównać rozmiar. Mam zawsze bezpłatną Automonous Database, która zawiera przykładowy schemat SSB. Jest stół LINEORDER, który ma kilkaset GB. Dostanę DDL z dbms_metadata
. Jedyną zmianą, którą musiałem zrobić, było sub(" NUMBER,"," NUMERIC,")
i wyłączyłem ograniczenia i klauzule sortowania.
Oczywiście istnieją profesjonalne narzędzia do konwersji schematu Oracle na PostgreSQL. Stary dobry ora2pg lub AWS SCT, który jest również świetny do oceny poziomu zmian wymaganych przez migrację. Ale jeśli chodzi o coś szybkiego, jestem dobry z awk
Następnie eksport jest łatwy dzięki set sqlformat csv
i kilka ustawień do wyprowadzania tylko danych, takich jak feedback off pagesize 0 long 999999999 verify off
. Przesyłam to wszystko do awk
który buduje \copy
polecenie, które pobiera te wiersze CSV bez zmian. Lubię robić małe kroki, a następnie budować 10000 linii poleceń KOPIUJ za pomocą (NR-data)%10000
, data
ustawiana na początku polecenia KOPIUJ. Wysyłanie ich równolegle byłoby łatwe, ale mogę tego nie potrzebować, ponieważ YugabyteDB jest wielowątkowy.
Oto skrypt, którego używam - mam portfel Autonomous Database w TNS_ADMIN, SQLcl zainstalowany w moim domu (bezpłatny ARM warstwy Oracle, na którym uruchamiam również moje laboratorium 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 "\\."
}
'
Wyjście może być bezpośrednio przesłane do psql
Oto mój ekran podczas uruchamiania ładowania:
Jest to laboratorium, mierzenie czasu, który upłynął, nie ma sensu, ale spojrzałem na rows_inserted
statystyki, aby sprawdzić, czy wszystko jest dystrybuowane do 3 węzłów mojej rozproszonej bazy danych SQL. Nawet w przypadku pojedynczej sesji klienta obciążenie rozkłada się na cały klaster.
Działa to tak samo dla PostgreSQL, ponieważ jest to ten sam interfejs API:YugabyteDB używa PostgreSQL na wierzchu rozproszonej pamięci masowej.
Wszystkie komponenty tego testu są bezpłatne i łatwe w użyciu:
- Maszyna wirtualna działa w warstwie Oracle Cloud Free (ARM), Oracle Database to bezpłatna autonomiczna baza danych 👉 https://www.oracle.com/cloud/free/
- PostgreSQL jest oprogramowaniem typu open source i darmowym 👉 https://www.postgresql.org
- YugabyteDB to oprogramowanie typu open source i bezpłatne 👉 https://www.yugabyte.com