Oracle에서 PostgreSQL 또는 YugabyteDB로 데이터를 전송하는 SQLcl 🅾🐘🚀

오래된 DBA는 Larry Ellison이 고객이 이사하는 것을 원하지 않았기 때문에 Oracle이 "SQL*Unloader"없이 "SQL*Loader"를 제공했다는 이야기를 가지고 있습니다. 이것은 변경되었습니다: SQLcl에서 간단한set sqlformat csv를 사용하여 CSV로 내보내는 쉬운 방법이 있습니다. 자세한 내용은 팔로우Jeff Smith blog하세요.

다음은 예입니다. 크기를 비교하기 위해 일부 샘플 데이터를 Oracle에서 YugabyteDB로 이동하고 싶었습니다. SSB 샘플 스키마가 포함된 항상 무료인 Automonous Database가 있습니다. 수백 GB의 LINEORDER 테이블이 있습니다. dbms_metadata 로 DDL을 얻습니다. 내가 해야 했던 유일한 변경은 sub(" NUMBER,"," NUMERIC,") 제약 조건과 데이터 정렬 절을 비활성화했습니다.

물론 Oracle 스키마를 PostgreSQL로 변환하는 전문 도구가 있습니다. 좋은 오래된ora2pg 또는 AWSSCT는 마이그레이션에 필요한 변경 수준을 평가하는 데도 좋습니다. 그러나 빠른 것을 위해 나는 awk가 좋습니다 😉

그런 다음 내보내기는 set sqlformat csvfeedback off pagesize 0 long 999999999 verify off 와 같은 데이터만 출력하는 몇 가지 설정으로 쉽습니다. 이 CSV 라인을 있는 그대로 사용하는 awk 명령을 빌드하는 \copy로 모든 것을 파이프합니다. 저는 작은 단계를 수행한 다음 COPY 명령의 시작 부분에 설정되는 (NR-data)%10000 , data 를 사용하여 10000줄 COPY 명령을 작성하는 것을 좋아합니다. 병렬로 보내기는 쉽지만 YugabyteDB는 다중 스레드이기 때문에 필요하지 않을 수 있습니다.

내가 사용하는 스크립트는 다음과 같습니다. TNS_ADMIN에 Autonomous Database 지갑이 있고 집에 SQLcl이 설치되어 있습니다(YugabyteDB 랩도 실행하는 Oracle 프리 티어 ARM).

{
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 통계를 보고 모든 것이 분산 SQL 데이터베이스의 3개 노드에 분산되어 있는지 확인했습니다. 단일 클라이언트 세션에서도 부하가 모든 클러스터에 분산됩니다.

이것은 동일한 API이기 때문에 PostgreSQL에서도 동일하게 작동합니다. YugabyteDB는 분산 스토리지 위에 PostgreSQL을 사용합니다.

이 테스트의 모든 구성 요소는 무료이며 사용하기 쉽습니다.
  • VM은 Oracle Cloud 프리 티어(ARM)에 있으며 Oracle 데이터베이스는 무료 자율 데이터베이스입니다 👉 https://www.oracle.com/cloud/free/
  • PostgreSQL은 오픈 소스이며 무료입니다 👉 https://www.postgresql.org
  • YugabyteDB는 오픈 소스이며 무료입니다 👉 https://www.yugabyte.com
  • 좋은 웹페이지 즐겨찾기