Mysql 5.7 -> 8.0 Upgrade

장준영·2024년 5월 3일

개요

현재 코인의 버전은 다음과 같다.

  • Redis 4.0.13
  • Mongodb 3.4.24
  • Mysql 5.7.39

자정이 넘은 12시 50분경 캠퍼스팀의 팀장이 공지를 하였다.
최근 Admin과 일부 기능을 제외한 normal API의 작업이 끝나 Stage서버에 WAS를 띄우게 되었다. 하지만 문제가 발생하였다. 현재는 DB를 완벽하게 분리하여 DB서버에 Stage서버용 Mysql 5.7.39버전이 올라가 있다. 문제는 새로 올린 SpringBoot 3버전에서는 Mysql 5.7버전을 지원하기 어려워 진다는 것이었다.
Mysql의 5.7은 2023년10월 부로 지원을 종료(EOS)했기에 버전을 올릴 필요가 있었다.

여러가지 방안을 찾아보다 Docker로 두가지 버전의 Mysql을 띄우기로 하였다.(Docker가 정말 필요해진 순간이었다)
일단 레가시인 Spring3에서 지원하는 가장 최신 버전인 8.0.29 버전으로 올리기로 하였다.
갑작스러운 요구였지만 세팅을 위해 빠르게 DB를 만들어주었다.

MySQL업그레이드시 고려사항

공식문서 및 여러가지 블로그를 참고하여 버전업시 고려사항을 살펴보았다.

먼저 코인의 데이터베이스를 분석해보자.

현재 KOIN_API의 MYSQL은 66개의 table을 가지고 있다.
KOIN_DB도 legacy이기 때문에 table의 연관관계가 상당히 복잡하다.
한번 미사용 테이블을 삭제하려는 시도가 있었지만 mybatis의 연관관계설정이 되었는 경우가 종종 있어 오류를 뿜어냄으로 보관중이다.

또한 DUMP파일의 용량은 800메가바이트 정도 된다.
일단 KOIN_DB는 dump파일이 800메가바이트 정도 되기 때문에 일반적인 source명령어나 import명령으로 이관시 메모리제한으로 fail이 나오기 때문에 메모리 제한을 늘려줘야 한다.

Migration에 대한 가이드는 DB_Migration_Guide 을 살펴보자.

고려해야할 테이블이 많이 있었다. API를 개발하면서 참조하는 데이터가 이렇게나 많이 있다는 것을 다시한번 느끼게 되었다.
여담으로 미사용 테이블 정리, 정규화(이미 진행하긴 하였다), 인덱싱, 옵티마이저등 개선해야할 부분도 많이 있다고 느꼈다.

일단 버전업시의 주의사항을 살펴보도록 하겠다.
먼저 블로그 등의 한글로된 주의사항을 읽어본 후 mysql공식매뉴얼을 확인하였다.

Mysql 5.7 ->8.0 고려사항

사용자 인증방식 변경 : Mysql8.0버전부터는 Caching SHA-2 Authentication 인증 방식이 기본인증방식으로 바뀌었다. Mysql5.7에 존재했던 사용자 계정은 여전히 Native Authentication인증 방식을 사용하겠지만 Mysql8.0버전에서 별도의 옵션없이 생성되는 사용자계정은 Caching SHA-2 Authentication 인증방식을 사용하게 된다. 만약 Native Authentication을 계속 사용하고자 한다면 Mysql 서버를 시작할때 --default-authentication-plugin=mysql_native_password파라미터를 활성화 해야 한다.

  • Native Authentication : 해당방식은 Mysql서버에 기본적으로 내장되어 있으며, 사용자의 계정정보와 암호를 Mysql의 내부 데이터 딕셔너리에 저장한다. native authentication방식에서는 사용자 계정과 암호가 Mysql의 'mysql.user'테이블에 저장된다. 암호는 해시된 형태로 저장되며, 암호를 비교할때 클라이언트에서 전달된 암호를 해시하여 저장된 암호와 비교한다. 이 방식은 Mysql서버에 대한 접근 제어 및 인즈을 처리하는데 사용된다.
  • Caching SHA-2 Authentication : 해당방식은 보안 향상을 위해 사용자 암호를 SHA-256해시로 저장하고, 통신과정에서 보안강화를 위해 SSL/TLS암호화를 사용한다.

MYSQL 8.0과의 호환성 체크 : Mysql8.0 업그레이드 전에 Mysql 5.7버전에서 손상된 FRM파일이나 호환되지 않는 데이터 타입 또는 함수가 있는지 mysqlcheck유틸리티를 이용해 확인한다.
확인사항으로는 TimeStamp(밀리세컨드까지 표기 가능)와 Char/Varchar(256->1024자 까지 확장)의 형식이 바뀌었으나 코인에서는 큰 문제가 없었다.

외래키 이름의 길이 : Mysql8에서는 외래키(Foreign key)의 이름이 64글자로 제한된다. 그래서 기존의 Mysql서버에서 외래키 이름이 64글자 이상인 것이 있는지 확인하고 필요하면 변경하여야 한다.
인덱스 힌트: Mysql 5.x에서 사용되던 인덱스 힌트가 있다면 Mysql8.0에서 먼저 성능테스트를 수행해야 한다. Mysql5.x에서는 성능 향상에 도움이 됐지만 Mysql 8.x에서는 오히려 성능 저하를 유발할 수도 있다.

파티션을 위한 공용 테이블스페이스 : Mysql8.x에서는 파티션의 각 테이블스페이스를 공용 테이블 스페이스에 저장 할 수 없다. 그래서 파티션의 테이블스페이스가 공용 테이블스페이스에 저장된 것이 있는지 먼저 확인하고, 있다면 ALTER TABLE ....REORGANIZE 명령을 실행해 개별 테이블스페이스를 사용하도록 변경해야 한다.

-> 바뀐 방식으로는 추후 Koin계정을 만들때는 바뀐 방법으로 계정 생성 후 권한을 줘야 한다.

Redis, MongoDB 업그레이드시 고려사항

일단 mysql버전업을 하여 한숨을 돌리게 되었다.
KOIN의 주 서버는 Mysql이긴 하지만 버스데이터의 정합성,캐싱의 필요성의 이유로 MongoDb와 Redis도 존재한다.
SpringBoot로 업그레이드를 하면서 호환성문제, db관리툴의 불편함(Mongodb버전이 낮아 MongodbCompass버전도 매우 낮아 접근이 불편하다)

때마침 이러한 니즈가 있었기에 위의 Redis, MongdoDB도 버전을 올리게 되었다.
다만 고려사항이 있다.
이전의 Redis재기동시 BGsave이슈로 문제가 된점,
레가시인 Spring3와 MongoDB의 호환성 문제로 MongoDB버전이 낮은점이 있었다.

1번안 같은 경우는 DB마운트로 Redis의 데이터베이스도 유지시키고, BGsave option을 끄면 해결이 된다.
2번의 경우는 legacy Koin은 현재 올릴수 있는 가장 높은 버전의 MongoDB를 이미 사용중이기 때문에 각기 다른 두개의 MongoDB을 사용하여 분기처리를 진행한다.

출처:
https://www.itworld.co.kr/t/54649/%EB%B9%85%20%EB%8D%B0%EC%9D%B4%ED%84%B0/296467
https://dev.mysql.com/doc/refman/8.0/en/
https://wonsjung.tistory.com/582
https://hoing.io/archives/17694
https://velog.io/@wujin/DB-AWS-RDS-MySQL-5.7-to-8.0-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98
https://cloud.google.com/sql/docs/mysql/upgrade-major-db-version-migrate?hl=ko

2개의 댓글

comment-user-thumbnail
2024년 11월 23일

고려할 사항이 엄청 많은거같은데 어떻게 다 알고 대처한거지? ㄷㄷ

1개의 답글