Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

SQLcl para transferir dados do Oracle para PostgreSQL ou YugabyteDB 🅾🐘🚀


DBAs antigos têm histórias sobre a Oracle fornecer um "SQL*Loader" sem qualquer "SQL*Unloader" porque Larry Ellison não queria que seus clientes saíssem. Isso mudou:há uma maneira fácil de exportar para CSV com um simples set sqlformat csv em SQLcl. Siga o blog de Jeff Smith para saber mais sobre isso.

Aqui está um exemplo. Eu queria mover alguns dados de amostra do Oracle para o YugabyteDB para comparar o tamanho. Eu tenho um Automonous Database sempre gratuito, que inclui o esquema de amostra SSB. Há uma tabela LINEORDER que tem algumas centenas de GB. Vou pegar o DDL com dbms_metadata . A única alteração que tive que fazer foi sub(" NUMBER,"," NUMERIC,") e desabilitei restrições e cláusulas de agrupamento.

Claro, existem ferramentas profissionais para converter um esquema Oracle para PostgreSQL. O bom e velho ora2pg, ou AWS SCT que também é ótimo para avaliar o nível de mudanças exigidas por uma migração. Mas para algo rápido, sou bom com awk 😉

Então a exportação é fácil com set sqlformat csv e as poucas configurações para gerar apenas dados como feedback off pagesize 0 long 999999999 verify off . Eu canalizo tudo isso para awk que cria o \copy comando que leva essas linhas CSV como estão. Eu gosto de fazer pequenos passos e então construir comandos COPY de 10.000 linhas com (NR-data)%10000 , data sendo definido no início do comando COPY. Enviá-los em paralelo seria fácil, mas talvez não precise porque o YugabyteDB é multithread.

Aqui está o script que eu uso - eu tenho minha carteira do Autonomous Database em TNS_ADMIN, SQLcl instalado em minha casa (um ARM de nível gratuito Oracle no qual também executo meu laboratório 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 "\\."
}
'

A saída pode ser canalizada diretamente para psql 😎

Aqui está minha tela ao iniciar o carregamento:

É um laboratório, medir o tempo decorrido não faz sentido, mas eu olhei para rows_inserted estatísticas para verificar se tudo está distribuído para os 3 nós do meu banco de dados SQL distribuído. Mesmo com uma única sessão de cliente, a carga é distribuída em todo o cluster.

Isso funciona da mesma forma para o PostgreSQL porque é a mesma API:YugabyteDB usa PostgreSQL em cima do armazenamento distribuído.

Todos os componentes deste teste são gratuitos e fáceis de usar:
  • A VM está no nível Oracle Cloud Free (ARM), o Oracle Database é um Autonomous Database gratuito 👉 https://www.oracle.com/cloud/free/
  • O PostgreSQL é de código aberto e gratuito 👉 https://www.postgresql.org
  • YugabyteDB é de código aberto e gratuito 👉 https://www.yugabyte.com