LLM WikiAccess-protected knowledge portal
← 스터디 홈
7편 · 약 22분

업그레이드 계획: 5.7→8.0/8.4, charset/collation, optimizer 변화

MySQL 업그레이드가 어려운 이유

MySQL 버전 업그레이드는 단순 패키지 교체가 아니다. 5.7에서 8.0으로의 전환은 인증 플러그인 기본값 변경, 새 예약어 추가, 기본 charset/collation 변경, 옵티마이저 동작 변경, SQL 모드 강화처럼 동작 방식이 실질적으로 달라지는 변화를 수반한다. 준비 없이 업그레이드하면 애플리케이션 오류, 쿼리 성능 저하, 복제 단절이 동시에 발생할 수 있다.

8.4 LTS는 8.0에서 deprecated된 기능을 제거하고 안정성을 높인 장기 지원 버전이다. 5.7 → 8.4는 직접 지원되지 않으므로 반드시 5.7 → 8.0 → 8.4 순서로 진행해야 한다.


업그레이드 경로

MySQL 5.7 EOL 2023-10-31 권장 경로 MySQL 8.0 EOL 2026-04 권장 경로 MySQL 8.4 LTS 지원 ~2032 직접 업그레이드 불가 ✕ MySQL 9.x Innovation
MySQL 업그레이드 경로

MySQL 8.0은 2026년 4월 EOL을 앞두고 있어, 현재 8.0을 운영 중이라면 8.4 LTS 전환 계획이 필요하다.


1단계: 사전 호환성 검사

업그레이드 전 가장 중요한 작업은 현재 서버에서 문제가 될 항목을 먼저 찾는 것이다.

MySQL Shell upgrade checker

# MySQL Shell 실행 후 (8.0 Shell로 현재 5.7 서버에 접속)
mysqlsh -- util checkForServerUpgrade \
    root@localhost:3306 \
    --target-version=8.0

이 도구는 수십 가지 항목을 자동으로 점검한다.

  • 새 예약어와 충돌하는 스키마/컬럼명
  • utf8mb3으로 분류되는 컬럼 (utf8은 8.0에서 utf8mb3의 별칭)
  • deprecated SQL 모드 사용 여부
  • ZEROFILL, FLOAT/DOUBLE AUTO_INCREMENT (8.4에서 제거됨)
  • mysql_native_password 사용 계정

mysqlcheck

# 테이블 손상 및 업그레이드 호환성 확인
mysqlcheck --all-databases --check-upgrade -u root -p

2단계: charset/collation 변화 이해와 대응

5.7 → 8.0에서 가장 많이 운영자를 놀라게 하는 변화 중 하나가 기본 charset과 collation의 변경이다.

항목MySQL 5.7 기본값MySQL 8.0+ 기본값
character_set_serverlatin1utf8mb4
collation_serverlatin1_swedish_ciutf8mb4_0900_ai_ci
character_set_clientlatin1utf8mb4

중요한 점: 업그레이드 자체가 기존 테이블의 collation을 바꾸지는 않는다. 이미 존재하는 컬럼은 원래 collation을 유지한다. 문제가 생기는 경우는 두 가지다.

  1. dump/reload 방식 업그레이드: mysqldump 없이 CREATE TABLE 구문에 collation을 명시하지 않으면, 신규 로드 시 새 기본값(utf8mb4_0900_ai_ci)이 적용된다.
  2. PAD 동작 차이: utf8mb4_0900_ai_ci는 NO PAD collation이어서 'abc''abc '(공백 포함)를 다른 값으로 취급한다. 기존 utf8mb4_general_ci(PAD SPACE)는 동일하게 취급한다.
-- 현재 데이터베이스/테이블의 charset과 collation 확인
SELECT
    TABLE_SCHEMA,
    TABLE_NAME,
    TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
  AND TABLE_COLLATION NOT LIKE 'utf8mb4_0900%'
ORDER BY TABLE_SCHEMA, TABLE_NAME;

-- 컬럼 단위 확인
SELECT
    TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME,
    CHARACTER_SET_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE COLLATION_NAME IS NOT NULL
  AND COLLATION_NAME NOT LIKE 'utf8mb4_0900%'
ORDER BY TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME;

애플리케이션이 trailing space 비교에 의존하거나, 기존 인덱스와 신규 인덱스의 collation이 섞이면 인덱스를 활용하지 못하거나 JOIN 결과가 달라질 수 있다. 업그레이드 전에 collation 목록을 정리하고 필요시 명시적으로 변환한다.

-- 테이블 전체 charset/collation 변환 예시
ALTER TABLE orders
  CONVERT TO CHARACTER SET utf8mb4
  COLLATE utf8mb4_0900_ai_ci;

3단계: 예약어와 SQL 모드 변화

8.0은 새 예약어를 대거 추가했다. RANK, GROUPS, LAG, LEAD, FIRST_VALUE, LAST_VALUE, NTH_VALUE, CUME_DIST, DENSE_RANK, PERCENT_RANK 등이 예약어가 됐다. 이 단어들을 컬럼명이나 테이블명으로 쓰고 있다면 반드시 백틱으로 escape하거나 이름을 변경해야 한다.

-- 예시: 5.7에서 정상, 8.0에서 오류
SELECT rank FROM leaderboard;

-- 8.0 이후 올바른 표현
SELECT `rank` FROM leaderboard;

SQL 모드도 8.0에서 기본값이 강화됐다. NO_AUTO_CREATE_USER는 8.0에서 제거됐고, ONLY_FULL_GROUP_BY는 8.0 기본 모드에 포함된다. GROUP BY 없이 비집계 컬럼을 SELECT하는 쿼리가 5.7에서는 경고만 나왔다면 8.0에서는 오류가 된다.

-- 현재 SQL 모드 확인
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

4단계: 인증 플러그인 변화

5.7의 기본 인증 플러그인은 mysql_native_password였다. 8.0에서는 caching_sha2_password가 기본이 됐고, 8.0 후반부터 mysql_native_password는 deprecated, 9.0에서 완전 제거됐다.

-- 현재 native_password를 사용하는 계정 목록
SELECT User, Host, plugin
FROM mysql.user
WHERE plugin = 'mysql_native_password';

-- caching_sha2_password로 변경
ALTER USER 'appuser'@'%' IDENTIFIED WITH caching_sha2_password BY 'NewPassword!';

클라이언트 라이브러리(JDBC, mysqlclient 등)가 구버전이라면 caching_sha2_password를 지원하지 않아 연결에 실패할 수 있다. 업그레이드 전에 클라이언트 드라이버 버전도 함께 확인해야 한다.


5단계: 옵티마이저 변화

8.0 주요 옵티마이저 변화

8.0에서 옵티마이저가 개선되면서 기존에 사용하던 쿼리의 실행계획이 바뀔 수 있다.

  • prefer_ordering_index: ORDER BY + LIMIT 쿼리에서 옵티마이저가 ordered index를 선호한다. 드물게 기존보다 느린 계획을 선택할 수 있다.
  • Hash Join: 8.0.18부터 hash join이 도입됐다. nested loop가 항상 최선이 아닌 경우 자동으로 hash join을 사용한다.
  • ONLY_FULL_GROUP_BY: 기본 활성. GROUP BY 쿼리 재검토 필요.
  • optimizer_trace_max_mem_size: 16KB → 1MB로 증가. 옵티마이저 트레이스가 잘리지 않아 분석이 쉬워졌다.
-- 옵티마이저 스위치 확인
SELECT @@optimizer_switch;

-- 특정 최적화만 비활성화 (문제 쿼리 임시 회피)
SET optimizer_switch = 'prefer_ordering_index=off';

8.0 → 8.4 주요 변화

8.4는 8.0에서 deprecated된 기능을 제거했다.

항목8.0 상태8.4 상태
slave_* 변수deprecated제거 (→ replica_*)
FLOAT/DOUBLE AUTO_INCREMENTdeprecated제거
mysql_native_password 플러그인 기본값동작함비활성화 기본
LOCK TABLES ... WRITE (no-op 버전)deprecated제거
Foreign key on non-unique index허용기본 제한 (restrict_fk_on_non_standard_key)
-- 8.4 업그레이드 전: replica_* 변수명 확인
SHOW VARIABLES LIKE 'replica_%';

-- 8.0에서 slave_* 변수 사용 중이면 모니터링 스크립트/알림도 같이 수정 필요
SHOW VARIABLES LIKE 'slave_%';

실전 업그레이드 절차

① 사전 검사 checkForServerUpgrade · mysqlcheck · charset/collation 목록 · 예약어 충돌 · 드라이버 버전 ② 스테이징 환경 검증 프로덕션 데이터 복제 → 업그레이드 → 주요 쿼리 실행계획 비교 · 애플리케이션 통합 테스트 ③ 물리 백업 (xtrabackup) 전체 백업 확보 · binary log position 기록 · 복구 리허설 완료 확인 ④ Replica 먼저 업그레이드 (rolling) Replica 한 대씩 업그레이드 → 복제 lag 확인 → 모니터링 → Primary는 마지막 ⑤ Primary 업그레이드 및 검증 유지보수 창 → Primary 업그레이드 → 복제 재확인 → 애플리케이션 연결 복구 → 7일 집중 모니터링
MySQL 업그레이드 실전 절차

Replica 먼저 업그레이드하는 이유

MySQL은 상위 버전 replica가 하위 버전 primary의 binlog를 읽는 것을 허용한다(역방향은 불가). 따라서 replica를 먼저 업그레이드하면 Primary가 여전히 구버전인 상태에서 replica가 신버전을 검증할 수 있다. 문제가 생기면 replica를 롤백하거나 다른 replica로 전환해 서비스를 유지할 수 있다.


업그레이드 롤백 계획

업그레이드는 항상 롤백 계획과 함께 진행해야 한다.

현실적인 롤백 경로:

  • Primary 업그레이드 전이라면: replica를 구버전으로 내리고 다시 구버전 primary에 붙이는 것이 가장 빠르다.
  • Primary까지 업그레이드된 후: 물리 백업에서 구버전으로 복원. 업그레이드 후 기록된 binlog는 구버전으로 재현할 수 없으므로 해당 기간의 데이터 변경은 손실될 수 있다.

8.0 → 8.4에서 실제 데이터 파일 포맷 변경은 없으므로, mysqld 바이너리만 교체 가능한 설정이라면 바이너리 롤백이 가능한 경우도 있다. 하지만 공식 지원 경로는 아니므로 사전에 검증해야 한다.


실전 체크리스트 요약

사전 점검
□ util.checkForServerUpgrade() 실행 → 경고 전부 해결
□ mysqlcheck --all-databases --check-upgrade 실행
□ 예약어 충돌 컬럼·테이블명 확인 및 백틱 처리 또는 이름 변경
□ mysql_native_password 계정 목록화 → caching_sha2_password 전환 계획
□ FLOAT/DOUBLE AUTO_INCREMENT 컬럼 제거 (→ 8.4 대상)
□ slave_* 변수 → replica_* 변경 (→ 8.4 대상)
□ charset/collation 혼재 목록 정리 → NO PAD 동작 영향도 확인
□ 클라이언트 드라이버 버전 확인 (caching_sha2_password 지원 여부)

스테이징 검증
□ 프로덕션 데이터로 업그레이드 리허설 완료
□ 주요 쿼리 실행계획 변화 없음 확인 (EXPLAIN 비교)
□ 애플리케이션 통합 테스트 통과

실행 단계
□ 전체 물리 백업 확보 및 복구 테스트 완료
□ Replica 순차 업그레이드 → 복제 lag 정상 확인
□ Primary 유지보수 창 업그레이드
□ 복제 상태 재확인 (SHOW REPLICA STATUS)
□ 알림 임계값 재설정 (slave_* → replica_* 메트릭 변경 포함)

References

  • MySQL 8.4 Reference Manual, "What Is New in MySQL 8.4 since MySQL 8.0": https://dev.mysql.com/doc/refman/8.4/en/mysql-nutshell.html
  • MySQL 8.4 Reference Manual, "Variables Deprecated or Removed": https://dev.mysql.com/doc/refman/8.4/en/added-deprecated-removed.html
  • MySQL Shell 8.4, "Upgrade Checker Utility": https://dev.mysql.com/doc/mysql-shell/8.4/en/mysql-shell-utilities-upgrade.html
  • MySQL 8.4 Release Notes, "Changes in MySQL 8.4.0": https://dev.mysql.com/doc/relnotes/mysql/8.4/en/news-8-4-0.html
  • PlanetScale Blog, "How to Upgrade from MySQL 5.7 to 8.0": https://planetscale.com/blog/upgrading-to-mysql-8
  • Skeema.io, "MySQL 5.7 to 8.0: Schema and DDL Changes": https://www.skeema.io/blog/2024/02/28/mysql57-to-8-upgrade/
  • Microsoft Tech Community, "7-Point Checklist to Conquer MySQL 5.7 to 8.0 Upgrade Challenges": https://techcommunity.microsoft.com/blog/adformysql/7-point-checklist-to-conquer-mysql-5-7-to-8-0-upgrade-challenges/4286547
  • Microsoft Tech Community, "Guide to Upgrade Azure Database for MySQL from 8.0 to 8.4": https://techcommunity.microsoft.com/blog/adformysql/guide-to-upgrade-azure-database-for-mysql-from-8-0-to-8-4/4493669
  • Percona Blog, "MySQL 8.0 Deprecated Features: What You Need to Know": https://www.percona.com/blog/mysql-8-0-deprecated-features-what-you-need-to-know/
  • MySQL Blog Archive, "New Defaults in MySQL 8.0": https://dev.mysql.com/blog-archive/new-defaults-in-mysql-8-0/