brunch

MySQL 5.7 → 8.0 버전업 사례

by 멘토사피엔스

실제 MySQL 버전업 진행 사례


57억 건의 데이터를 가진 운영 DB, 수백 개의 테이블. 전수 조사를 생략한 채 MySQL 8.0으로의 전환을 무사히 마칠 수 있을까? 이 글은 그 도전과 전략을 기록한 실전 리포트입니다.


현 조직에서 약 2개월의 기간 동안 MySQL 버전업을 준비하고 타겟일정에 운영환경에서 성공적으로 MySQL 버전업을 완료했습니다. 새벽 작업을 통해 서비스를 중단하고 작업이 이루어졌으며 이 글에서 그 과정을 공유하고자 합니다.


작업 계획 설계


최초의 작업 계획을 아래와 같이 작성했습니다. 테스트 단계와 운영 서버 반영 단계로 나누어서 정리했습니다.


테스트 단계


1. 실환경과 동일한 수준의 MySQL 버전업


개발환경과 실환경의 데이터는 많은 차이가 있습니다. 실환경의 데이터가 있는 데이터베이스에서 발생 가능한 문제를 사전에 체크하는게 필요하다고 판단해, 실환경을 클론해서 MySQL 버전을 시도합니다.


Step 1. 기존 운영 환경에서 별도의 인스턴스를 클론 생성

Step 2. 8.0 변경을 위한 작업 선조치

이미 조사했던 이슈 중 우리 상황에 맞게 해결해야 될 부분이 있는지 파악하고 리스트업합니다. 그리고 필요하다고 판단되는 부분들을 선조치합니다.

Ex) 인덱스 설정 체크 / 인코딩 및 Collation 변경

Step 3. 운영 클론인스턴스 MySQL 버전업

버전업은 AWS에서 자체적으로 8.0 업그레이드를 진행합니다. AWS의 Pre condition 체크를 통해 발견된 문제를 선조치합니다.


2. 버전업 이후 데이터 전수 조사


각 테이블에 들어있는 데이터가 깨지거나 특별한 문제가 없는지 확인하는 작업입니다.


수백 개 테이블의 전수 검사는 현실적으로 불가능했습니다. 우리는 대신 “실제 문제가 생기는 건 쿼리 실행 단계”라는 관점을 가지고, 주요 API 흐름과 Native 쿼리 전수 실행으로 정합성을 확보하는 전략으로 전환했습니다.


대신 쿼리 및 API 테스트로 충분히 검증될 것이라 판단했습니다.


3. API를 활용하지 않는 Native 쿼리 전수 조사


PHP 모놀리식인 레거시가 운영 중에 있습니다 여기서 일부 기능이 API를 활용하지 않고 데이터를 읽고 쓰고 있기 때문에 API 테스트와 별개로 전수 실행해서 문제 없는지를 판단 합니다.


이상 있는 쿼리의 기준은 동작이 되지 않거나 심각하게 느려진 쿼리들입니다. 이들을 찾아 조치 방안을 마련하기로 합니다.


4. 버전업한 클론 인스턴스의 인프라 환경 구축


버전업된 클론인스턴스의 API를 테스트하고 QA를 진행할 수 있도록 인프라 환경을 구축합니다. 개발 환경 외에 별도로 인프라 환경을 구축하고 테스트하는 이유는 개발환경에서 문제 발생 시 내부 개발에 영향을 줄 것이라 판단했고 운영환경의 데이터를 기준으로 미리 테스트를 하는 것이 필요하다고 판단했기 때문입니다.


이 작업 역시 실제로 진행하지 않았습니다. 이미 갖추어진 개발환경에서 해당 작업을 진행하는것으로 결정했습니다. 클론 인스턴스를 위해 별도로 인프라 환경을 구축하는 리소스가 비효율적으로 판단되었고, 총 3번의 API 및 사용환경 테스트를 진행하기보다 개발, 운영에서 총 2번 진행하는 걸로 충분하다고 판단했습니다.


5. 어플리케이션 API 전수 테스트


앞서 별도로 구축한 인프라 환경에서 API를 전체 테스트합니다. 그리고 주요 코어 로직(로그인, 가입에서 결제에 이르기까지의 주요 퍼널)을 QA하기로 합니다.


6. 개발환경 버전업 및 API 전수 테스트


1번-5번 과정이 별도의 클론인스턴스를 버전업하고 테스트한 것이라면 이제 기존의 개발환경을 버전업하고 테스트합니다. 따라서 인프라 환경을 별도로 구축하는 것 외에 전 과정을 반복해서 테스트를 진행합니다. 더불어 일정기간 개발환경에서 사용하는 기간을 두어 그 기간 내에 별도로 발생하는 문제가 있다면 체크하고 대응합니다.


운영 배포 단계


테스트에서 문제를 해결하고 모든 조치 방안을 마련한 뒤 진행, 변경이 필요한 코드, 데이터는 미리 작업합니다.


롤백이 언제든 가능하도록 준비해둡니다.


서버는 미리 작업 공지를 한 뒤 당일날 서버를 내리고 진행을 합니다. 변경 후 전사 직원이 모니터링하고 발생하는 이상 현상 및 이슈에 대응합니다.


실제 작업 진행


실제 진행 시 변경된 부분들이 있었습니다. 가장 큰 변경은 운영환경과 동일한 데이터와 인프라를 만들어서 테스트하지 않았다는 점입니다. 그 대신 개발환경을 두 단계로 나누어 테스트를 진행했습니다.


테스트 단계


1. 개발환경에서의 MySQL 버전업


약 2년 전부터의 실환경 데이터가 있다는 점에서 운영환경의 데이터를 어느정도 검수할 수 있을것으로 가정했습니다. 따라서 개발환경의 인스턴스로 MySQL 버전업을 시도하는 작업으로 변경했습니다.


다만 버전업에 따른 이슈 발생 시 내부 구성원의 개발 작업에 영향을 주지 않기 위해 별도로 개발환경의 MySQL을 클론해서 버전업을 먼저 진행했습니다.


Step 1. 기존 운영 환경에서 별도의 인스턴스를 클론 생성

Step 2. 8.0 변경을 위한 작업 선조치

Collation - Collation 변경에는 약 85시간, 57억 건의 데이터 작업이 필요했습니다. 하지만 이 작업은 운영 중 리스크가 너무 컸고, 현재 utf8도 장기간 지원된다는 점을 고려해 ‘변경하지 않기로’ 결정했습니다. 대신 사후 쿼리 호환성 검증에 집중했습니다.

Date 컬럼 변경 - ‘0000-00-00’ 형태로 저장된 데이터가 굉장히 많았고 해당 데이터 기준으로 활용되는 로직도 파편화되어 있는 상황이었습니다. 이 역시 데이터를 다 변경하는 것에 대한 사이드이펙트가 예측하기 어려웠으므로 SQL_MODE를 변경하여 8.0에서 대응가능하도록 했습니다. 즉 NO_ZERO_DATE, NO_ZERO_INDATE 옵션을 비활성화했습니다

예약어 처리 - 예약어를 쓰게 되면 8.0 업데이트 자체가 불가하므로 예약어를 쓸 수 있도록 진행했습니다. 주요 전략은 백틱을 쿼리에 삽입해 예약어로 인식되지 않게 하는 방법이었습니다.

Step 3. 개발 클론인스턴스 MySQL 버전업

버전업은 AWS에서 자체적으로 8.0 업그레이드를 진행합니다. AWS의 Pre condition 체크를 통해 발견된 문제를 선조치합니다.

발견된 문제를 모두 해결하고 Pre condition을 통과했으며 버전업을 완료했습니다.

json default value를 JSON_OBJECT로 변경하기 위해 스크립트를 작성, 적용했습니다

Step 4. Native Query 전수 검사

버전업 이후 Native Query를 전수 실행해서 검사를 진행합니다. 쿼리 실행이 되지 않거나 느려진 것을 찾아 대응했습니다.


2. 개발 클론 버전업 환경 로컬테스트


개발 환경 테스트 이전에 로컬에서 개발 클론에서 버전업된 MySQL 테스트를 진행합니다. 크게 아래 3가지로 나누어 진행했습니다. 모든 API와 cron job, cdc가 정상동작하는지 테스트했으며 로그 모니터링을 통해 문제가 없는지 사후 확인을 진행하는 절차를 따랐습니다.

Spring 백엔드 API 테스트

PHP 백엔드 API 테스트

Cron job, CDC 전수 테스트

스케줄러에 의해 실행되는 Spring, PHP의 Job과 CDC를 임의로 실행시켜 전수 테스트했습니다.

데이터웨어하우스 사용 쿼리 테스트


3. 개발 환경 MySQL 버전업 진행 및 테스트


개발 환경을 버전업하고 테스트를 진행합니다. 기존 개발 DB를 백업해 롤백 상황을 대응하기로 합니다. 로컬테스트와 마찬가지로 3가지로 나누어 API 및 쿼리 테스트를 진행했습니다.


주요 API 테스트를 진행한 뒤 내부에서 실제 사용해보는 기간을 일주일 가지면서 추가로 발생하는 문제에 대응했습니다.


이 때 이슈는 의외로 다른 곳에서 발생했는데 AWS MSK로 운영되고 있는 카프카 커넥터가 생성되지 않은 점이었습니다. MySQL 버전업으로 인해 binlog source가 바뀌었고, 기존 connector가 이를 인식하지 못한 것입니다. 해결책은 간단했습니다 — database.server.id를 신규 인스턴스 기준으로 명시하면서 새 커넥터를 정의하는 것이었습니다.


→ 기존 계획 대비 테스트 단계의 차이점은 운영환경의 데이터베이스를 클론하지 않았으며, 별도릐 인프라를 따로 구축하지 않고 로컬에서 테스트를 진행한 점입니다. 리소스의 효율성을 고민한 결과였고 결론적으로 이 생략과정에 의해서 문제가 발생하지는 않았습니다.


운영 배포 단계

스크린샷 2025-05-10 오후 5.57.47.png 사용했던 Launch Plan 일부

운영 배포는 다음과 같이 이루어졌습니다.


1. 배포일 지정


2. 15일 전 파트너 업체에 작업 일정 공지

서비스 중단 시 내부 API를 사용하는 파트너 업체들에게 작업 일정을 사전 공지했습니다.


3. 배포일 새벽 서비스 중단

모든 서비스를 셧다운했고, 운영 중인 Kafka CDC 작업도 전체 중지했습니다.


4. 서비스 내 작업 공지 오픈

서비스 진입 시 유지보수 페이지로 리다이렉트해서 고객들에게 작업 공지를 알렸습니다.


5. 운영 DB 백업

현시점의 최신 데이터를 백업해 만일의 경우 롤백에 대응하기 위합입니다.


6. 운영환경 MySQL 5.7 → 8.0 버전업 진행

블루그린 엔진 업그레이드로 진행했고, json_default 스크립트 적용 및 sql_mode가 작업한대로 정상 적용되었는지 확인합니다.


7. MSK kafka connect 재생성

개발환경에서 대응한 경험이 있었기 때문에 큰 문제 없이 진행될 수 있었습니다.


8. 클러스터 신규 생성 및 블루그린 업그레이드 진행


9. 서비스 오픈


10. 전체 QA 및 API, JOB, CDC 테스트

운영 환경에서 전 직원이 나와서 QA를 진행하는 동시에 개발자들은 API 전수 테스트, Job과 CDC 테스트 및 확인 작업을 진행했습니다.


이로써 버전업 후 큰 문제 없이 전환이 완료되었습니다. 배포 직전, 내부망 QA 테스트를 시도했으나 사전 인프라 준비가 없어 그대로 전체 오픈으로 전환했습니다. 이 과정은 사전 리허설의 중요성을 다시 느끼게 했으며, 향후에는 “내부망 QA 전용 환경 확보”가 체크리스트에 포함돼야 할 부분이었습니다. 결국 전체 오픈을 하고 사용성테스트를 한다는 방향으로 선회했고 다행히 문제 없이 전환이 마무리될 수 있었습니다.


최대한 보수적으로 플래닝했고 최소한의 문제도 발생하지 않고자 했습니다. 진행 단계에서 의도치 않은 문제나 조금씩 리스크를 감당해야 하는 상황이 발생했지만 결국 롤백없이 MySQL 8.0 버전업을 잘 마무리 지을 수 있었습니다.


이 프로젝트는 ‘꼼꼼하게 테스트하되, 꼭 필요한 부분에만 자원을 투입하자’는 전략으로 성공했습니다. 예상치 못한 이슈에도 빠르게 대응하며, 롤백 없이 성공적으로 전환 완료. 덕분에 월 $5,500의 유지비를 절감하며 기술 부채도 함께 해소할 수 있었습니다.







FinOps 커뮤니티에 함께 하실래요?


저는 최근 48%, $36000의 AWS 비용절감을 달성했습니다.

클라우드 비용을 효율화하고 싶은 분들, 비슷한 고민을 나누고 싶다면 제가 운영 중인 AWS-FINOPS-KR Slack 커뮤니티에 참여하세요. 실제 절감 사례, 질문, 전략 공유를 나누실 수 있습니다.


⇒ [FinOps Slack 참여하기]


keyword
매거진의 이전글MySQL 5.7 → 8.0 버전업 시 주의사항