본문 바로가기

Database

mysqldbcopy를 이용한 DB to DB copy

mysqldbcopy를 써보자

물리적으로 분리된 동기종간 data sync를 위해 mysqldbcopy를 사용해 봤습니다.


windows

mysqldbcopy를 사용하기 위해서는 mysql utilities를 설치해야합니다.

https://downloads.mysql.com/archives/utilities/ 

 

MySQL :: Download MySQL Utilities (Archived Versions)

MySQL Utilities is now covered under Oracle Lifetime Sustaining Support Per Oracle's Lifetime Support policy, as of May 30, 2018, MySQL Utilities is covered under Oracle Sustaining Support. Some features of Utilities are on the roadmap for Shell, users are

downloads.mysql.com


Linux

yum install mysql-utilities

아래와 같은 오류 발생시

# mysqlfrm
Traceback (most recent call last):
  File "/usr/bin/mysqlfrm", line 27, in <module>
    from mysql.utilities.common.tools import (check_python_version,
ImportError: No module named utilities.common.tools

yum install mysql-connector-python.noarch 설치후

yum install mysql-utilities 설치


 

utilities에 포함된 프로그램중 mysqldump도 있는데, 

mysqldump를 통해 sync 작업을 할 수있으나, online 상에서 바로 sync되는 구조가 아닌

origin DB에서 데이터를 로컬로 저장 후 -> target DB로 데이터를 복사하는 

2번? 작업을 통해 원본데이터를 출력 / 입력하는 구조로 되어 있어서 mysqldbcopy를 사용해봤습니다.
(사실 그냥 한번 써보고 싶었습니다)

mysqldbcopy -d --source=user:'패스워드'@호스트:포트--destination=user:'패스워드'@호스트:포트 DB명:DB명  
#-d 옵션 : 복사가 되어야 하는 target DB의 DB를 우선 삭제하고 복사
#해당 옵션이 없는 상태에서 매번 DB복사가 이뤄져할때면 이미 있는 DB로 인식하고 datacopy 실패

장점. 단한번의 명령줄로 DB to DB간 스키마 및 데이터 sync가 가능

단점. target DB는 매번 스키마를 지우고 재생성되는 구조로 sync됨


적용

1. 위의 shell을 bat 스크립트로 작성

2. windows 스케쥴러에 등록 매일 1회 실행


고찰

그냥 향후에는 아마 오리지날 DB를 read replica형태로 해서 제공하지 않을까 싶습니다.

그냥 단순히 저 기능이 어떻게 동작하는건지 궁금했던것 같습니다 후후후

 


7/1 추가.

daily로 mysqldbcopy를 하던중 에러와 직면하게 됩니다.

ERROR: Problem updating blob field. Error = Query failed. 1292 (22007): Truncated incorrect DOUBLE value: ''

해당 에러로 문제가 발생하는 테이블들 이후에 데이터는 sync가 되고 있지 않았습니다.

 

해당 에러는 구글링 해보닌깐, update/insert시 컬럼의 type가 실제 value값의 type이 맞지 않을때 발생한다고 합니다.

즉, varchar 문자열 구문에서 문자열이 아닌값이 입력될때 문제가 발생한다라는 내용같습니다.

다만, 테이블의 데이터를 아무리 봐도 문제점이 뭔지 쉽게 파악되지 않을듯했습니다.

하여, 문제가 있는 테이블을 exclude하여 copy를 시도해 봤습니다.

mysqldbcopy -d --source=user:'패스워드'@호스트:포트--destination=user:'패스워드'@호스트:포트 DB명:DB명 -xtable
#-x <포함하기싫은 table명> ex. -x user 

이렇게 하니, 문제가 있는 table은 제외되고 copy가 되어 모든 테이블이 sync가 되었으나....최초에 copy하기전 모든 테이블을 drop한다고 했었죠?

맞습니다. 문제가 있는 테이블은 데이터가 삭제된채로 sync 제외라서 사용할 수 없는 상태였습니다.

결국 저는 read replica로 가게되었습니다.(처음부터갔어야...)

 

read replica는 오리지날 DB의 복제본 및 읽기전용으로 생성이 되어 쓰기는 불가능합니다.

또한 현재 리전 말고도 다른 리전으로 생성이 가능하고, 필요에 따라서 master(쓰기가능)으로 승격도 가능합니다.

문득 궁금했습니다. 복제본을 뜰때 운영중인 DB에 어떤 영향을 주는지?

  • Single 모드에서 Read replica를 생성할때 영향을 주지 않음(snapshot 기반으로 복제)
    단, 생성한지 얼마 되지 않은 RDS인 경우 snapshot을 사용하지 못할때, 운영RDS에 직접 복제를 하므로 영향을 줄 수 있으나, downtime이 발생하는건 아니고 IOPS를 좀 쓰게됨
  • MultiAZ 모드에서는 stanby 중인 RDS를 대상으로 작업이 발생하여, 운영RDS에는 전혀 영향을 주지 않음