기존 퍼블릭으로 구축된 rds 인스턴스 private 인스턴스로 이관하기
예전에 같이 일했던 대표님의 제안으로 대표님이 운영하시는 스타트업에 이직하게 되었다.
기존에 구축한 서비스를 분석하던중 이전 개발자분이 rds db 구축을 퍼블릭 인스턴스로 만들었다.
나는 public으로 세팅되어 있는 db를 private로 세팅하고 싶었고 db는 backend ec2 서버에서만 접속이 가능하도록 하고 싶었다.
일단 private로 rds 인스턴스를 생성하였고,
기존 퍼블릭 인스턴스 db의 데이터를 dump떠서 private 인스턴스 db로 복원한 생각이었다.
처음에는 dbeaver툴을 사용하여 손쉽게 dump파일 생성과 restore 처리를 할 생각이었지만 public db인스턴스의 데이터베이스를 dump를 뜨니깐 아래와 같은 오류발생.
챗지피터한테 물어보니 mysqldump명령어에 --ignore-table이나 --skip-lock-tables 옵션을 추가하라고 하는데 나는 dbeaver 툴로 dump를 실행하고 있었고 저 옵션을 어디에 넣어야 할지도 모르겠고 그냥 ec2에 접속하여 rds의 db와 연결하여 dump를 뜨기로 했다.
2025-01-23 16:36:05.714 - IO error: Utility 'mysqldump' not found in client home '/opt/homebrew/Cellar/mysql/9.2.0/bin/mysqldump' (/opt/homebrew/Cellar/mysql/9.2.0/bin/mysqldump)
2025-01-23 16:36:05.714 - java.io.IOException: Utility 'mysqldump' not found in client home '/opt/homebrew/Cellar/mysql/9.2.0/bin/mysqldump' (/opt/homebrew/Cellar/mysql/9.2.0/bin/mysqldump)
at org.jkiss.dbeaver.utils.RuntimeUtils.getNativeClientBinary(RuntimeUtils.java:152)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLDatabaseExportHandler.fillProcessParameters(MySQLDatabaseExportHandler.java:102)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLDatabaseExportHandler.fillProcessParameters(MySQLDatabaseExportHandler.java:1)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLNativeToolHandler.getCommandLine(MySQLNativeToolHandler.java:76)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLDatabaseExportHandler.getCommandLine(MySQLDatabaseExportHandler.java:83)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLDatabaseExportHandler.getCommandLine(MySQLDatabaseExportHandler.java:1)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.executeProcess(AbstractNativeToolHandler.java:218)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.doExecute(AbstractNativeToolHandler.java:285)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLNativeToolHandler.doExecute(MySQLNativeToolHandler.java:47)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.lambda$0(AbstractNativeToolHandler.java:88)
at org.jkiss.dbeaver.runtime.RunnableContextDelegate.lambda$0(RunnableContextDelegate.java:39)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:124)
/opt/homebrew/Cellar/mysql-client/9.2.0/bin/mysqldump --skip-lock-tables --routines --add-drop-table --disable-keys --extended-insert -u admin --host=nowswing-prod-db.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com --port=3306 now_swing
Task 'MySQL dump' started at Thu Jan 23 16:36:58 KST 2025
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.
Warning: A dump from a server that has GTIDs enabled will by default include the GTIDs of all transactions, even those that were executed during its extraction and might not be represented in the dumped data. This might result in an inconsistent data dump.
In order to ensure a consistent backup of the database, pass --single-transaction or --lock-all-tables or --source-data.
mysqldump: Couldn't execute 'SELECT LIBRARY_NAME FROM INFORMATION_SCHEMA.LIBRARIES WHERE LIBRARY_SCHEMA = 'now_swing' ORDER BY LIBRARY_NAME': Unknown table 'LIBRARIES' in information_schema (1109)
Task 'MySQL dump' finished at Thu Jan 23 16:37:02 KST 2025
2025-01-23 16:37:02.312 - IO error: Process failed (exit code = 2). See error log.
2025-01-23 16:37:02.312 - java.io.IOException: Process failed (exit code = 2). See error log.
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.validateErrorCode(AbstractNativeToolHandler.java:264)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.executeProcess(AbstractNativeToolHandler.java:242)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.doExecute(AbstractNativeToolHandler.java:285)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLNativeToolHandler.doExecute(MySQLNativeToolHandler.java:47)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.lambda$0(AbstractNativeToolHandler.java:88)
at org.jkiss.dbeaver.runtime.RunnableContextDelegate.lambda$0(RunnableContextDelegate.java:39)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:124)
/opt/homebrew/Cellar/mysql-client/9.2.0/bin/mysqldump --skip-lock-tables --routines --add-drop-table --disable-keys --extended-insert -u admin --host=nowswing-prod-db.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com --port=3306 now_swing
Task 'MySQL dump' started at Thu Jan 23 16:37:10 KST 2025
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.
Warning: A dump from a server that has GTIDs enabled will by default include the GTIDs of all transactions, even those that were executed during its extraction and might not be represented in the dumped data. This might result in an inconsistent data dump.
In order to ensure a consistent backup of the database, pass --single-transaction or --lock-all-tables or --source-data.
mysqldump: Couldn't execute 'SELECT LIBRARY_NAME FROM INFORMATION_SCHEMA.LIBRARIES WHERE LIBRARY_SCHEMA = 'now_swing' ORDER BY LIBRARY_NAME': Unknown table 'LIBRARIES' in information_schema (1109)
Task 'MySQL dump' finished at Thu Jan 23 16:37:13 KST 2025
2025-01-23 16:37:13.778 - IO error: Process failed (exit code = 2). See error log.
2025-01-23 16:37:13.778 - java.io.IOException: Process failed (exit code = 2). See error log.
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.validateErrorCode(AbstractNativeToolHandler.java:264)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.executeProcess(AbstractNativeToolHandler.java:242)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.doExecute(AbstractNativeToolHandler.java:285)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLNativeToolHandler.doExecute(MySQLNativeToolHandler.java:47)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.lambda$0(AbstractNativeToolHandler.java:88)
at org.jkiss.dbeaver.runtime.RunnableContextDelegate.lambda$0(RunnableContextDelegate.java:39)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:124)
/opt/homebrew/Cellar/mysql-client/9.2.0/bin/mysqldump --skip-lock-tables --routines --add-drop-table --disable-keys --extended-insert -u admin --host=nowswing-prod-db.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com --port=3306 now_swing
Task 'MySQL dump' started at Thu Jan 23 16:37:36 KST 2025
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.
Warning: A dump from a server that has GTIDs enabled will by default include the GTIDs of all transactions, even those that were executed during its extraction and might not be represented in the dumped data. This might result in an inconsistent data dump.
In order to ensure a consistent backup of the database, pass --single-transaction or --lock-all-tables or --source-data.
mysqldump: Couldn't execute 'SELECT LIBRARY_NAME FROM INFORMATION_SCHEMA.LIBRARIES WHERE LIBRARY_SCHEMA = 'now_swing' ORDER BY LIBRARY_NAME': Unknown table 'LIBRARIES' in information_schema (1109)
Task 'MySQL dump' finished at Thu Jan 23 16:37:39 KST 2025
2025-01-23 16:37:39.695 - IO error: Process failed (exit code = 2). See error log.
2025-01-23 16:37:39.695 - java.io.IOException: Process failed (exit code = 2). See error log.
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.validateErrorCode(AbstractNativeToolHandler.java:264)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.executeProcess(AbstractNativeToolHandler.java:242)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.doExecute(AbstractNativeToolHandler.java:285)
at org.jkiss.dbeaver.ext.mysql.tasks.MySQLNativeToolHandler.doExecute(MySQLNativeToolHandler.java:47)
at org.jkiss.dbeaver.tasks.nativetool.AbstractNativeToolHandler.lambda$0(AbstractNativeToolHandler.java:88)
at org.jkiss.dbeaver.runtime.RunnableContextDelegate.lambda$0(RunnableContextDelegate.java:39)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:124)
일단 아래 명령어를 ec2에서 실행했을때 로컬에서는 안됐던 dump파일이 생성되었다.
그리고 다시 dump파일을 private 인스턴스에 복원해봤다.
mysqldump -h nowswing-prod-db.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com --port=3306 -u admin -p --databases now_swing --routines --triggers --events > dump-now-swing-back.sql
mysql -h db-nowswing-prod.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com -u admin -p now_swing < /home/ubuntu/dump/dump-now-swing-back.sql
ERROR 1227 (42000) at line 24: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation 오류 발생......
이후에 아래와 같은 오류 발생 access denied라는 걸 보니 대충 권한 문제인듯 싶다.
구글링을 해보았다.
일단 DEFINER 가 명시된 부분을 지워주고 아래 SET으로 시작되는 부분을 찾아서 주석처리해주면 된다고 한다.
해보기로 했다.
일단 sed 시작되는 부분만 처리해주고 dump 파일을 복원했을때 정상적으로 처리되었다.
sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i <FILENAME>.sql
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
엥? 근데 이상하다.. 왜 다른 데이터베이스의 trigger들이 복원된거지?........
일단 다시 생성된 데이터베이스를 날린후 다시 복원해보기로 했다.
아무래도 mysqldump라는 명령어의 --triggers라는 옵션이 지정한 데이터베이스와 상관없이 모든 triggers들을 가져온듯 하다.
그래서 그냥 데이터베이스만 지정하여 mysqldump명령어를 실행해보기로 했다.
아래 명령어를 실행하여 다시 definer이 포함된 부분을 지워줬다
set부분까지 지웠다. 그런데 dump파일을 새로운 private 인스턴스에 복원했을때 안된다...
ERROR 1231 (42000) at line 993: Variable 'sql_log_bin' can't be set to the value of 'NULL' 오류 발생
mysqldump -h nowswing-prod-db.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com --port=3306 -u admin -p --databases now_swing --routines --triggers --events > /home/ubuntu/dump/dump-now-swing-back.sql
sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i /home/ubuntu/dump/dump-now-swing-back.sql
-- dump파일에 아래 내용들 주석처리
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
챗지피터한테 물어보기로 했다.
장문에 오류를 복붙하고 '아래 오류 해결방법을 알려줘' ^^
그런데 확 눈에 들어오는거 하나!!! 바로 --set-gtid-purged=OFF
/opt/homebrew/Cellar/mysql-client/9.2.0/bin/mysqldump --set-gtid-purged=OFF --skip-lock-tables --routines --add-drop-table --disable-keys --extended-insert -u admin --host=nowswing-prod-db.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com --port=3306 now_swing
다시 mysqldump명령어 부터 실행하여 처음부터 다시 시작했다.
아주 깔끔하게 dump파일이 생성되었다.
마지막으로 private 인스턴스 db에 dump 파일을 복원해봤다.
아주 깔끔하게 복원되었다!!!
mysqldump --set-gtid-purged=OFF -h nowswing-prod-db.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com --port=3306 -u admin -p --databases now_swing --routines --triggers --events > /home/ubuntu/dump/dump-now-swing-back.sql
mysql -h db-nowswing-prod.c7uuccqaam4k.ap-northeast-2.rds.amazonaws.com -u admin -p now_swing < /home/ubuntu/dump/dump-now-swing-back.sql
이렇게 일단 private 인스턴스 db에 기존 public 인스턴스 db의 데이터들을 모두 이관하였다.
이후에 ec2에서 바라보고 있는 public db를 private 인스턴스 db로 바라보도록 변경해야 한다.
일단 ec2를 ssh로 접속하여 nc -zv {private 인스턴스 엔트포인트} 3306 를 쳐봤다.
당연히 ec2와 private db와 통신이 되니깐 dump파일 복원이 되었겠지만.. 기존 서비스의 환경을 건드리는건 언제나 무서운일...
정확히 succeeded라는 단어가 떠야 뭔가 안심이 될거 같았다.
자! 이젠 backend 코드의 환경설정 파일에 db정보를 변경해주자.
하지만... 나는 dump파일을 다른 db인스턴스환경에 성공적으로 복원했다고 한들 기존 사이트와 동일하게 기능들이 동작하는지 보고 싶었다.
기존 서비스에 영향이 가면 안되기 때문에 나는 서비스되지 않는 새로운 ec2를 생성하여 private db인스턴스와 연결할 기존에 운영되고 있는 같은 환경에 프론트엔드와 백엔드 소스를 배포하였다.
그러고 나서 기존 서비스되고 있는 플랫폼과 새로 구축한 운영되고 있지 않은 플랫폼의 기능들이 정상적으로 동작하는데 핵심 메뉴들만 체크해보기로 하고 이상이 없으면 완전하게 기존 서비스되고 있는 백엔드 서비스를 새로 생성한 private db인스턴스에 연결하기로 했다.
예전에 나였으면 정상적으로 완료됐으니깐 괜찮겠지 생각하며 바로 백엔드 코드가 바라보는 db 인스턴스를 private로 변경하였겠지만, 이젠 귀찮고 번거롭더라도 확실히 짚고 넘어가는 습관을 들이려고 노력하고 있고 그래야 나의 성장시킬수 있는거 같다.