Старите DBA имат истории за Oracle, предоставящ "SQL*Loader" без никакъв "SQL*Unloader", защото Лари Елисън не искаше клиентите му да се изнесат. Това се промени:има лесен начин за експортиране в CSV с прост set sqlformat csv
в SQLcl. Следвайте блога на Джеф Смит, за да научите повече за него.
Ето един пример. Исках да преместя някои примерни данни от Oracle в YugabyteDB, за да сравня размера. Имам винаги безплатна Automonous Database, която включва примерната схема на SSB. Има таблица LINEORDER, която е няколко стотици GB. Ще получа DDL с dbms_metadata
. Единствената промяна, която трябваше да направя, беше sub(" NUMBER,"," NUMERIC,")
и деактивирах ограниченията и клаузите за съпоставяне.
Разбира се, има професионални инструменти за конвертиране на Oracle схема в PostgreSQL. Добрият стар ora2pg или AWS SCT, който също е чудесен за оценка на нивото на промените, изисквани от миграция. Но за нещо бързо, аз съм добър с awk
😉
Тогава експортирането става лесно с set sqlformat csv
и няколкото настройки за извеждане само на данни като feedback off pagesize 0 long 999999999 verify off
. Прехвърлям всичко това към awk
който изгражда \copy
команда, която приема тези CSV редове такива, каквито са. Обичам да правя малки стъпки и след това да създавам 10000 реда команди COPY с (NR-data)%10000
, data
се задава в началото на командата COPY. Изпращането им паралелно би било лесно, но може да не ми трябва, защото YugabyteDB е многонишков.
Ето скрипта, който използвам - имам портфейла си за автономна база данни в TNS_ADMIN, SQLcl, инсталиран в дома ми (безплатен ARM от Oracle, на който също стартирам моята лаборатория 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 "\\."
}
'
Резултатът може директно да се прехвърли към psql
😎
Ето моя екран при стартиране на зареждането:
Това е лаборатория, измерването на изминало време няма смисъл, но погледнах rows_inserted
статистика, за да потвърдя, че всичко е разпределено до 3-те възела на моята разпределена SQL база данни. Дори и с една клиентска сесия, натоварването се разпределя върху целия клъстер.
Това работи по същия начин за PostgreSQL, защото е същият API:YugabyteDB използва PostgreSQL върху разпределеното хранилище.
Всички компоненти в този тест са безплатни и лесни за използване:
- ВМ е на ниво Oracle Cloud Free (ARM), Oracle Database е безплатна автономна база данни 👉 https://www.oracle.com/cloud/free/
- PostgreSQL е с отворен код и е безплатен 👉 https://www.postgresql.org
- YugabyteDB е с отворен код и е безплатен 👉 https://www.yugabyte.com