[Tech]Azure SQL Database에서 AWS RDS PostgrSQL로의 데이터베이스 마이그레이션

데이터베이스 마이그레이션은 기존에 사용하던 데이터베이스에서 다른 데이터베이스로 변경하는 것을 의미합니다. 갖고 있는 데이터를 새로운 데이터베이스로 옮겨야 합니다. 많은 DBMS 제품들이 비슷한 점도 있지만 각자 데이터를 관리하는 방법도 다르고 장단점이 있습니다. 그래서 데이터베이스 마이그레이션은 빈번하게 발생하는 요구사항이고 서비스를 온프레미스에서 클라우드로 옮길 때도 필요한 작업입니다. 


이번 글에서 다룰 작업은 Azure SQL DATABASE와 AWS RDS PostgreSQL 간의 마이그레이션입니다. 고객의 요구에 의한 작업이었는데, 보시다시피 마이그레이션이 DBMS의 종류가 다를 수도 있고, 클라우드 서비스를 공급해 주는 회사도 다를 수도 있습니다. 


이번 마이그레이션의 결론은 AWS DMS를 쓰고 후처리를 하면 되는데, 이 결론까지 오는데 마주쳤던 우여곡절들과 대처했던 방법들을 공유하려 합니다. 


들어가기에 앞서, 소스와 타깃이 다른 종류의 DBMS일 경우 DB MIGRATION을 진행하면서 가장 크게 신경 써야 할 부분 중에 하나는 두 DBMS의 자료형이 다르기 때문에 이것에 맞춰서 알맞게 옮겨줘야 한다는 것입니다. 이번 작업에서는 geometry라는 특이한 자료형이 있었습니다. 


저는 2가지 시도를 진행하였습니다. 


1. 'AWS DMS'로 마이그레이션 시도


AWS DMS는 AWS Database Migration Service의 약자로 AWS에서 제공하는 마이그레이션을 도와주는 서비스입니다. 

 


처음에 AWS DMS로 시도를 했었는데, 데이터를 옮기고 보니 SQL Server에서 geometry이던 자료형이 PostgreSQL에선 text로 바뀌었습니다. 

 

SQL Server의 자료형 



AWS DMS가 선택한 자료형 


 

해결책을 생각해보며 생각해뒀던 다른 방법인 2번을 같이 진행했습니다. 



2.'bcp'로 마이그레이션 시도 


SQL Server의 유틸리티인 bcp(bulk copy program utility)는 테이블을 데이터 파일로 만들 수 있고, 그 데이터 파일을 테이블에 넣을 수 있습니다. PostgreSQL의 copy명령어도 기능이 비슷해서 bcp를 이용해서 text파일로 내려받고, 그 text를 copy명령어로 PostgreSQL에 넣는 방식으로 마이그레이션을 계획했습니다. 


 


예를 들어 다음 처럼 명령을 내릴 수 있는데 

 

파라미터들에 대한 대략적인 설명은 아래와 같습니다. 


  • -C : 65001 UTF로 만들기 위함. 
  • -c : 문자 유형으로 다운 
  • -t : 딜리미터를 \t 탭으로 
  • -r : 생략했는데, 개행문자 CR+LF 가 들어갔다는 의미


bcp에서 out 옵션을 쓰면 테이블의 데이터를 그대로 export 할 수 있는데 PostgreSQL의 Copy Command는 Row Delimiter가 Line Feedback으로 고정되어 있고 Column Delimiter를 Tab으로 쓸 계획인데 Delimiter가 Data안에 이미 존재하면 Parsing에 문제가 생기므로 Escape문자를 붙여서 미리 Replace합니다. 


REPLACE(COL1, '\', '\\')
REPLACE(COL1, CHAR(13) + CHAR(10), '\n')
REPLACE(COL1, CHAR(10), '\n')
REPLACE(COL1, CHAR(13), '\n')
REPLACE(COL1, CHAR(9), '\t')


SQL Server의 Geometry데이터타입은 CLR타입이기 때문에 대응하는 PostgreSQL의 타입이 없어서 WKT포맷으로 해주기 위해 STAsText()함수로 변환해서 내려 받습니다. 


COPY에서 빈 문자열을 NULL로 처리하기 위해서 '\N'으로 수정합니다.


sed 's|^\t|\\N|g'
sed 's|\t\r|\t\\N\r|g' 


문자열 타입(varchar, nvarchar, text)의 경우에 null이 아닌 빈 문자열은 0x00으로 내려받아지는데 copy가 이걸 처리할 수 없습니다. COPY에서 처리 불가능한 0x00을 빈 문자열로 수정합니다.


sed 's|\x0||g'  


이렇게 전처리를 마쳤고, 마이그레이션을 진행하면 됩니다. 그 와중에 처음에 진행했던 DMS의 막혔던 부분에서 해결책이 나왔습니다. 


3.DMS로 해결하는 방법 두 가지 


3.1. AWS DMS를 사용해서 스키마와 데이터를 모두 옮기는 방법 


이렇게 하면 geometry가 text로 바뀌는데, alter table명령으로 해당 컬럼을 geometry로 바꿔줍니다. 


3.2 스키마를 먼저 만들고 데이터를 옮기는 방법. 


PostgreSQL쪽 테이블의 미리 만들어 컬럼을 geometry자료형으로 하면 옮길 때 알맞게 들어갑니다. 


이때 DMS를 사용하면서 데이터를 옮기는데 주의해야 할 부분 중 PostgreSQL의 대소문자 이슈가 있었습니다. SQL Server에선 테이블명을 대소문자를 구분해서 만들어도 select할 때 어떻게 적든 잘 기능합니다. 그런데 PostgreSQL에선 큰 따옴표를 붙이면 대소문자 구분을 하기 때문에, 테이블을 만들 때 큰따옴표를 붙이고 대문자를 포함했다면, select할 때도 큰따옴표를 붙여서 대문자를 맞춰서 적어줘야 합니다. 


이때 AWS DMS는 따옴표를 붙여서 테이블을 만들어줍니다. 그렇게 되면 후에 개발자가 select할 때 대소문자를 생각하고 따옴표를 붙여서 개발해야 하는 이슈가 있었습니다. 이 부분은 그림의 AWS DMS 변환 규칙 옵션으로 해결할 수 있습니다. 


 



Azure SQL Database에서 AWS RDS PostgrSQL로의 데이터베이스 마이그레이션의 해결 방법 2가지를 공유드렸습니다. 아래의 링크도 함께 참고 부탁드립니다. 

 

🔗 참고 링크

bcp 유틸리티

STAsText(geometry 데이터 형식)





-Lead Engineering Team 김지수











데이터베이스 마이그레이션이 필요하신가요? 클라우드 이기종 + 오픈소스 DBMS 데이터 마이그레이션의 컨설팅이나 기술지원이 필요하시다면 클라우드메이트로 연락주세요. 데이터 및 애플리케이션 마이그레이션 계획 수립, 리프트 앤 시프트(Lift and Shift), 리플랫폼(Replatform), 리팩터링(Refactoring) 전략 실행, 마이그레이션 실행 및 데이터 이전 방안 제시해드립니다. 

구축 및 마이그레이션 바로가기