업그레이드 계획: 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 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 -p2단계: charset/collation 변화 이해와 대응
5.7 → 8.0에서 가장 많이 운영자를 놀라게 하는 변화 중 하나가 기본 charset과 collation의 변경이다.
| 항목 | MySQL 5.7 기본값 | MySQL 8.0+ 기본값 |
|---|---|---|
| character_set_server | latin1 | utf8mb4 |
| collation_server | latin1_swedish_ci | utf8mb4_0900_ai_ci |
| character_set_client | latin1 | utf8mb4 |
중요한 점: 업그레이드 자체가 기존 테이블의 collation을 바꾸지는 않는다. 이미 존재하는 컬럼은 원래 collation을 유지한다. 문제가 생기는 경우는 두 가지다.
- dump/reload 방식 업그레이드: mysqldump 없이
CREATE TABLE구문에 collation을 명시하지 않으면, 신규 로드 시 새 기본값(utf8mb4_0900_ai_ci)이 적용된다. - 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_INCREMENT | deprecated | 제거 |
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_%';실전 업그레이드 절차
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/