카테고리 : MySQL/기술노트

MySQL 업그레이드 전략: 5.7에서 8.0, 8.0 minor upgrade 체크리스트

MySQL 5.7에서 8.0으로의 전환과 8.0 패치 업그레이드에서 호환성, 복제 전환, 성능 회귀, 복구 경계를 검증하는 절차를 정리한다.

저자: MySQL 기술 노트 작성: 2026.10.24 약 12분 6,850자
다운로드

1. 업그레이드의 완료 조건은 서버 기동이 아니다

MySQL 업그레이드는 실행 파일을 바꾸는 작업이 아니라 저장 형식, 서버 동작, 애플리케이션 계약을 함께 변경하는 작업이다. 새 버전이 연결을 받아도 인증 드라이버가 실패하거나, 비교 규칙이 바뀌거나, 특정 쿼리의 실행 계획이 악화되면 서비스 전환은 성공한 것이 아니다.

5.7에서 8.0으로의 전환은 데이터 딕셔너리와 호환성 변경을 중심으로 설계한다. 같은 8.0 계열의 패치 업그레이드는 변경 폭이 상대적으로 작지만, 옵티마이저 수정·설정 변경·복제 기능 차이 때문에 별도의 회귀 시험이 필요하다. 두 작업을 동일한 체크리스트로 실행하되 검증 깊이와 복구 경계를 다르게 정해야 한다.

이 글은 기존 5.7/8.0 시스템의 전환 절차를 다룬다. 8.0을 장기 최종 도착점으로 권고하는 글은 아니다. 실제 목표 버전은 지원 기간, 운영체제·드라이버 지원, 8.4 LTS까지의 후속 경로를 함께 평가해 선정한다. 최신 패치 번호는 작업 시점에 공식 배포 정보와 지원 정책으로 확정한다.

검증 범위: 아래 SQL은 폐기용 MySQL 8.0 인스턴스에서 실행한 진단 및 호환성 축소 예제다. 실제 5.7 datadir 업그레이드, 버전 혼합 복제, MySQL Shell Upgrade Checker 실행, Aurora 업그레이드는 이 글의 실험에 포함하지 않았다. SQL 성공을 해당 전환의 성공 증거로 확대해서는 안 된다.

2. 지원 경로와 되돌리기 경계를 먼저 확정한다

2.1 버전 문자열을 생략하지 않는다

Community MySQL의 공식 8.0 업그레이드 경로는 5.7 GA에서 8.0 GA로의 전환을 지원한다. 공식 문서는 다음 계열로 이동하기 전에 현재 계열의 마지막 릴리스로 올릴 것을 권고한다. 5.6에서 8.0으로 건너뛰는 방식은 지원 경로가 아니다. 현재 버전과 목표 버전은 5.7, 8.0이 아니라 정확한 패치 번호로 기록하고, 그 조합의 제한을 확인한다.

8.0 계열 안에서도 중간 릴리스를 무조건 순차 설치해야 하는 것은 아니다. 지원되는 경로인지 확인한 뒤, 건너뛰는 모든 릴리스의 비호환 변경을 검토하는 것이 핵심이다. 플러그인, 키링, OS 라이브러리, 백업 도구도 서버와 별도로 버전 호환성을 확인한다.

2.2 바이너리 교체와 복구를 구분한다

5.7에서 8.0으로 바뀐 datadir을 다시 5.7로 열 수 있다고 가정하면 안 된다. 8.0에서 5.7로의 다운그레이드는 지원되지 않는다. 실패 복귀의 기본 경로는 업그레이드 전 백업을 별도 환경에 복원하거나, 보존해 둔 구버전 환경으로 통제된 전환을 수행하는 것이다.

반대로 “8.0은 어떤 패치 사이에서도 in-place downgrade가 불가능하다”는 설명도 정확하지 않다. 공식 문서는 8.0.35부터 8.0 계열 내부의 in-place downgrade를 지원하며, 그보다 낮은 버전으로의 하향은 거부될 수 있다고 설명한다. 따라서 실제 원본·목표 조합의 제한을 확인해야 한다. 이 지원 사실만으로 되돌리기를 무시험으로 승인해서는 안 된다. 애플리케이션이 새 기능이나 새 데이터를 사용했다면 별도의 호환성 문제가 남는다.

복구 계획에는 다음 두 시점을 분리해 적는다.

  • 새 writer의 업무 쓰기 전: 기존 writer를 확실히 차단한 상태에서 전환을 취소하고 원래 경로를 재개할 수 있는지 확인한다.
  • 새 writer의 업무 쓰기 후: 이전 환경은 더 이상 최신 데이터가 아닐 수 있다. 변경분 재적용, 정합성 대조, 허용 손실량의 판단 없이 연결만 되돌리지 않는다.
flowchart TD
    A[정확한 버전 경로와 복구 수단 확정] --> B[사전 검사와 복원 리허설]
    B --> C[실제 드라이버와 대표 업무 회귀 시험]
    C --> D[쓰기 차단과 최종 적용 경계 확인]
    D --> E[새 환경 검증]
    E --> F{업무 쓰기 개방 여부}
    F -->|아직 개방 전| G[검증 실패 시 전환 취소 검토]
    F -->|개방 후| H[변경분 보존을 포함한 복구 절차]
    E --> I[점진적 트래픽 전환과 성능 관측]

3. 5.7에서 8.0으로 바뀌는 내부 동작

데이터 딕셔너리 전환

8.0은 테이블 등의 메타데이터를 트랜잭션 데이터 딕셔너리에서 관리한다. 5.7의 파일 기반 메타데이터 체계와 동일하지 않으므로, 첫 기동은 단순 프로세스 시작이 아니라 메타데이터 전환을 포함한다. 테이블 수, 객체 정의의 이상, 중단된 작업 이력에 따라 점검과 전환 시간이 달라진다. 데이터 용량만으로 소요 시간을 예측해서는 안 된다.

8.0.16부터는 서버가 이전에 mysql_upgrade가 담당하던 업그레이드 작업을 수행한다. 오래된 절차를 복사해 “데몬 기동 후 mysql_upgrade만 실행하면 완료”라고 정하면 검증이 빠진다. 오류 로그에서 딕셔너리·시스템 테이블 처리가 끝났는지 확인하고 실제 쿼리를 실행해야 한다. --upgrade=MINIMAL은 일반 서비스 전환을 위한 완료 상태와 같지 않으며, 작업 시간을 줄이기 위한 무조건적인 우회 수단이 아니다.

인증·설정·SQL 계약

  • 인증: 8.0의 기본 인증 방식 변화는 새 계정 생성과 클라이언트 연결 경로에 영향을 준다. 기존 계정이 모두 자동으로 새 플러그인으로 바뀐다고 가정하지 않는다. 실제 계정의 인증 플러그인, TLS 설정, 커넥터 버전, 연결 풀의 재연결을 조합해 시험한다.
  • 제거된 설정: Query Cache 관련 설정처럼 8.0에서 제거된 항목은 단순히 효력이 없어지는 데 그치지 않고 기동 실패 원인이 될 수 있다. 실행 중 변수 목록뿐 아니라 실제 옵션 파일과 서비스 실행 인자를 검사한다.
  • SQL 의미: 새 예약어, sql_mode, 날짜 처리, 문자셋·collation, 암묵적 형 변환을 점검한다. ONLY_FULL_GROUP_BY는 8.0에서 처음 생긴 제약이 아니다. 이미 5.7에서도 기본 설정에 포함되므로 버전 이름보다 현재 세션의 실제 설정 차이를 봐야 한다.
  • 실행 계획: 새 옵티마이저가 항상 기존 쿼리를 빠르게 만드는 것은 아니다. 추정 행 수, 조인 순서, 임시 테이블, 정렬, 범위 접근 변경이 편향된 데이터에서 회귀를 만들 수 있다.

기존 테이블의 collation은 서버 기본값이 바뀐다는 이유만으로 모두 자동 변환되지 않는다. 다만 신규 DDL이나 스키마를 다시 만드는 논리 이관에서 기본값을 생략하면 원본과 다른 정의가 생길 수 있다. 따라서 서버 기본값과 실제 컬럼 정의를 따로 비교한다.

4. 사전 검사: 체크 도구와 수동 검토의 역할

MySQL Shell의 util.checkForServerUpgrade()는 5.7과 8.0 인스턴스의 업그레이드 호환성 문제를 검사한다. 목표 버전과 Shell 버전을 명시적으로 맞춰야 한다. 목표 버전을 생략하면 도구 버전에 따른 대상이 선택될 수 있어 계획한 전환과 다른 검사가 된다.

아래는 환경에 맞게 채우는 MySQL Shell JavaScript 호출 구조다. 실행 결과를 제시하는 예제가 아니며, 계정 권한과 대상 접근은 공식 문서의 요구사항을 적용한다. 암호는 코드에 넣지 않고 도구의 안전한 입력 경로를 사용한다.

util.checkForServerUpgrade("upgrade_audit@db.example.com:3306", {
  targetVersion: "<정확한 목표 버전>",
  configPath: "<검사할 실제 옵션 파일의 로컬 경로>",
  outputFormat: "JSON"
});

configPath는 Shell 실행 위치에서 읽을 수 있는 실제 설정 파일 경로다. 원격 서버의 파일 경로를 문자열로 적는 것만으로 그 파일을 자동 취득하지 않는다. 파일 검사에 필요한 옵션을 누락해 검사가 실패했다면 “오류가 없었다”로 처리하지 않는다. include 파일, 서비스 인자, 동적·영속화 설정도 함께 대조한다.

검사 결과는 오류 수 외에 실행되지 못한 검사, 경고, 수동 조치 항목을 모두 검토한다. 성공 결과도 애플리케이션 SQL, 외부 ETL, 인증서, 운영 도구, 성능을 모두 보장하지 않는다. 별도로 다음 자료를 모아야 한다.

  1. 원본·목표 설정의 차이와 각 차이의 승인 사유.
  2. 엔진별 테이블 목록, 파티션 정의, 뷰·루틴·트리거·이벤트와 DEFINER.
  3. 계정·권한·인증 플러그인 및 실제 커넥터 연결 시험.
  4. 복구 가능한 백업과 binlog 보존 구간, 실제 복원 소요 시간.
  5. 대표 SQL의 결과 집합과 실행 계획, 처리량·지연의 기준값.

5. 실행 가능한 진단과 의미 회귀 예제

5.1 서버·세션 계약 확인

다음은 대상 서버의 기초 계약을 기록하는 쿼리다. 연결 문자셋은 클라이언트가 바꿀 수 있으므로 서버 기본값과 분리한다. 운영 계정·드라이버로도 같은 항목을 수집해야 한다.

SELECT VERSION() AS server_version,
       @@GLOBAL.lower_case_table_names AS lower_case_table_names,
       @@GLOBAL.character_set_server AS server_charset,
       @@GLOBAL.collation_server AS server_collation;
SELECT @@SESSION.character_set_connection AS connection_charset,
       @@SESSION.collation_connection AS connection_collation,
       FIND_IN_SET('ONLY_FULL_GROUP_BY', @@SESSION.sql_mode) > 0 AS full_group_by,
       FIND_IN_SET('STRICT_TRANS_TABLES', @@SESSION.sql_mode) > 0 AS strict_mode;

실행 결과(MySQL 8.0.x):

mysql> SELECT VERSION() AS server_version,
    ->        @@GLOBAL.lower_case_table_names AS lower_case_table_names,
    ->        @@GLOBAL.character_set_server AS server_charset,
    ->        @@GLOBAL.collation_server AS server_collation;

+----------------+------------------------+----------------+--------------------+
| server_version | lower_case_table_names | server_charset | server_collation   |
+----------------+------------------------+----------------+--------------------+
| 8.0.46         |                      0 | utf8mb4        | utf8mb4_0900_ai_ci |
+----------------+------------------------+----------------+--------------------+
1 row in set (0.00 sec)

mysql> SELECT @@SESSION.character_set_connection AS connection_charset,
    ->        @@SESSION.collation_connection AS connection_collation,
    ->        FIND_IN_SET('ONLY_FULL_GROUP_BY', @@SESSION.sql_mode) > 0 AS full_group_by,
    ->        FIND_IN_SET('STRICT_TRANS_TABLES', @@SESSION.sql_mode) > 0 AS strict_mode;

+--------------------+----------------------+---------------+-------------+
| connection_charset | connection_collation | full_group_by | strict_mode |
+--------------------+----------------------+---------------+-------------+
| latin1             | latin1_swedish_ci    |             1 |           1 |
+--------------------+----------------------+---------------+-------------+
1 row in set (0.00 sec)

출력은 테스트 클라이언트로 연결한 한 환경의 관측값이다. 이 연결은 latin1을 사용했으며, 서버 기본 문자셋이 utf8mb4여도 연결 설정은 별개라는 점을 보여 준다. 이를 권장 연결 문자셋으로 해석해서는 안 된다. 모든 운영 연결의 기본값을 나타내지도 않는다. 특히 lower_case_table_names는 8.0 초기화 시점의 설정 제약을 갖기 때문에 기존 datadir에서 값을 바꾸는 작업을 이름 대소문자 문제의 일반 해결책으로 삼지 않는다.

5.2 실제 객체 정의와 예약어 확인

폐기용 스키마에 작은 테이블을 만들고 엔진·collation·파티션 사용 여부를 확인한다. 운영에서는 TABLE_SCHEMA 조건을 실제 업무 스키마로 바꾸되, 대량 메타데이터 조회 비용과 조회 권한을 먼저 확인한다. KEYWORDS 조회는 8.0 대상 측 검사다. 이 객체가 5.7에도 있다고 가정해 원본에 그대로 실행하지 않는다.

CREATE TABLE upgrade_inventory (
  id BIGINT NOT NULL PRIMARY KEY,
  label VARCHAR(40) CHARACTER SET utf8mb4
    COLLATE utf8mb4_bin NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
SELECT t.TABLE_NAME, t.ENGINE, t.TABLE_COLLATION,
       MAX(p.PARTITION_NAME IS NOT NULL) AS is_partitioned
FROM information_schema.TABLES AS t
JOIN information_schema.PARTITIONS AS p
  ON p.TABLE_SCHEMA = t.TABLE_SCHEMA AND p.TABLE_NAME = t.TABLE_NAME
WHERE t.TABLE_SCHEMA = DATABASE()
  AND t.TABLE_NAME = 'upgrade_inventory'
GROUP BY t.TABLE_NAME, t.ENGINE, t.TABLE_COLLATION;
SELECT WORD, RESERVED
FROM information_schema.KEYWORDS
WHERE WORD IN ('RANK', 'WINDOW')
ORDER BY WORD;
DROP TABLE upgrade_inventory;

실행 결과(MySQL 8.0.x):

mysql> CREATE TABLE upgrade_inventory (
    ->   id BIGINT NOT NULL PRIMARY KEY,
    ->   label VARCHAR(40) CHARACTER SET utf8mb4
    ->     COLLATE utf8mb4_bin NOT NULL
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT t.TABLE_NAME, t.ENGINE, t.TABLE_COLLATION,
    ->        MAX(p.PARTITION_NAME IS NOT NULL) AS is_partitioned
    -> FROM information_schema.TABLES AS t
    -> JOIN information_schema.PARTITIONS AS p
    ->   ON p.TABLE_SCHEMA = t.TABLE_SCHEMA AND p.TABLE_NAME = t.TABLE_NAME
    -> WHERE t.TABLE_SCHEMA = DATABASE()
    ->   AND t.TABLE_NAME = 'upgrade_inventory'
    -> GROUP BY t.TABLE_NAME, t.ENGINE, t.TABLE_COLLATION;

+-------------------+--------+-----------------+----------------+
| TABLE_NAME        | ENGINE | TABLE_COLLATION | is_partitioned |
+-------------------+--------+-----------------+----------------+
| upgrade_inventory | InnoDB | utf8mb4_bin     |              0 |
+-------------------+--------+-----------------+----------------+
1 row in set (0.01 sec)

mysql> SELECT WORD, RESERVED
    -> FROM information_schema.KEYWORDS
    -> WHERE WORD IN ('RANK', 'WINDOW')
    -> ORDER BY WORD;

+--------+----------+
| WORD   | RESERVED |
+--------+----------+
| RANK   |        1 |
| WINDOW |        1 |
+--------+----------+
2 rows in set (0.00 sec)

mysql> DROP TABLE upgrade_inventory;

Query OK, 0 rows affected (0.00 sec)

예약어 목록 자체는 애플리케이션의 문제가 발견되었다는 뜻이 아니다. 테이블·컬럼·별칭·프로시저 이름 및 ORM 생성 SQL이 해당 단어를 인용 없이 사용하는지 조사해야 한다. 저장 객체의 본문과 동적 SQL은 테이블 목록만으로 검사가 끝나지 않는다.

5.3 실행 성공과 결과 의미가 다를 수 있다

다음은 동일한 데이터를 서로 다른 비교 규칙으로 조회하는 축소 실험이다. 5.7과 8.0 서버의 자동 변환을 재현한 것이 아니다. utf8mb4_bin으로 보존한 두 문자열을 그대로 비교한 경우와, 대소문자를 구분하지 않는 8.0 collation을 명시한 경우의 distinct 개수를 비교한다.

SET NAMES utf8mb4;
CREATE TABLE upgrade_semantics (
  id INT NOT NULL PRIMARY KEY,
  code VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  amount INT NOT NULL
) ENGINE=InnoDB;
INSERT INTO upgrade_semantics VALUES (1, 'A', 10), (2, 'a', 20);
SELECT COUNT(DISTINCT code) AS binary_distinct,
       COUNT(DISTINCT code COLLATE utf8mb4_0900_ai_ci) AS ai_ci_distinct
FROM upgrade_semantics;
SELECT code COLLATE utf8mb4_0900_ai_ci AS grouped_code,
       COUNT(*) AS grouped_rows, SUM(amount) AS total_amount
FROM upgrade_semantics
GROUP BY code COLLATE utf8mb4_0900_ai_ci;
SELECT id, code, amount FROM upgrade_semantics ORDER BY id;
DROP TABLE upgrade_semantics;

실행 결과(MySQL 8.0.x):

mysql> SET NAMES utf8mb4;

Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE upgrade_semantics (
    ->   id INT NOT NULL PRIMARY KEY,
    ->   code VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
    ->   amount INT NOT NULL
    -> ) ENGINE=InnoDB;

Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO upgrade_semantics VALUES (1, 'A', 10), (2, 'a', 20);

Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT COUNT(DISTINCT code) AS binary_distinct,
    ->        COUNT(DISTINCT code COLLATE utf8mb4_0900_ai_ci) AS ai_ci_distinct
    -> FROM upgrade_semantics;

+-----------------+----------------+
| binary_distinct | ai_ci_distinct |
+-----------------+----------------+
|               2 |              1 |
+-----------------+----------------+
1 row in set (0.00 sec)

mysql> SELECT code COLLATE utf8mb4_0900_ai_ci AS grouped_code,
    ->        COUNT(*) AS grouped_rows, SUM(amount) AS total_amount
    -> FROM upgrade_semantics
    -> GROUP BY code COLLATE utf8mb4_0900_ai_ci;

+--------------+--------------+--------------+
| grouped_code | grouped_rows | total_amount |
+--------------+--------------+--------------+
| A            |            2 |           30 |
+--------------+--------------+--------------+
1 row in set (0.00 sec)

mysql> SELECT id, code, amount FROM upgrade_semantics ORDER BY id;

+----+------+--------+
| id | code | amount |
+----+------+--------+
|  1 | A    |     10 |
|  2 | a    |     20 |
+----+------+--------+
2 rows in set (0.00 sec)

mysql> DROP TABLE upgrade_semantics;

Query OK, 0 rows affected (0.00 sec)

두 문자열이 하나의 비교 그룹으로 합쳐져도 원본 행이 자동 삭제되는 것은 아니다. 애플리케이션에서는 고유 키 충돌, 검색 결과 확대, 그룹 집계 변화로 이어질 수 있다. 그룹의 표시 문자열은 동등한 값 중 어떤 표현이 선택되느냐에 의존하므로 그 대소문자를 계약으로 삼지 않는다. 핵심 증거는 distinct 개수, 그룹 행 수, 합계와 원본 행 보존이다.

마이그레이션 회귀 시험에서는 SQL 오류 유무 외에 정렬 순서, 페이지 경계, NULL 처리, 소수점·시간 값, 중복 정의를 비교해야 한다. GROUP BY가 결과를 자동 정렬해 줄 것이라 기대하지 말고 순서가 필요하면 ORDER BY를 명시한다. 이 예제의 collation을 모든 테이블의 일괄 변환 목표로 권고하는 것은 아니다.

6. 전환 방식: in-place와 별도 환경

6.1 In-place 전환

같은 서버의 datadir을 목표 버전으로 전환하는 방식은 구성이 단순하지만, 서비스 중단과 복구 시간을 함께 부담한다. 사전 검사 완료 후 쓰기를 차단하고, 장기 트랜잭션·XA 상태·DDL·배치 작업을 정리한다. 정상 종료와 백업의 일관성 경계를 확보한 뒤 승인된 설치 절차로 전환한다. 강제 종료한 파일 복사본을 검증된 백업처럼 취급해서는 안 된다.

기동 후에는 로그의 업그레이드 완료뿐 아니라 객체 수·권한·주요 업무 SQL·스케줄 작업을 검사한다. 새 버전 시작 직후의 cold cache 지연과 지속적인 계획 회귀를 구별하되, 캐시가 차오를 것이라는 이유로 무제한 대기하지 않는다. 사전에 정한 지연·오류율·최대 관측 시간으로 중단 여부를 판정한다.

6.2 별도 환경과 복제 기반 전환

구버전을 보존하면서 신버전 환경을 준비하면 업무 시험과 전환 시간을 분리할 수 있다. 다만 비용과 절차가 늘고, 복제 호환성 및 최종 쓰기 경계를 직접 통제해야 한다.

일반적인 방향은 구버전 source에서 신버전 replica로 적용한 뒤 replica부터 검증하는 것이다. 신버전에서 구버전으로의 복제가 일반적으로 지원된다고 가정하지 않는다. ROW 형식이어도 DDL과 binlog 기능 차이가 사라지는 것은 아니다. 특히 새 writer의 변경을 구버전으로 역복제하면 언제든 되돌릴 수 있다는 설계는 별도 지원 확인과 시험 없이는 성립하지 않는다.

전환 시에는 애플리케이션의 신규 쓰기를 막고 진행 중 트랜잭션을 정리한 뒤 최종 GTID 또는 binlog 경계를 기록한다. 후보가 그 경계까지 적용했는지, 적용 오류가 없는지, 필요한 데이터가 일치하는지 확인한다. Seconds_Behind_Source가 0이거나 수신 스레드가 정상이라는 사실만으로 완료를 판정하지 않는다. 기존 writer는 연결 경로 변경과 별도로 쓰기를 차단하여 이중 쓰기를 예방한다.

7. 8.0 minor upgrade에서 줄이면 안 되는 검증

패치 업그레이드의 단위는 서버 패키지가 아니라 서버·설정·접속 드라이버·운영 도구의 조합이다. 목표 릴리스의 버그 수정 목록에서 사용 중인 기능을 찾고, 중간 릴리스의 비호환 변경까지 추적한다. 아래 항목은 메이저 전환보다 작게 수행할 수는 있어도 생략하기 어렵다.

  • 계획 회귀: 주요 digest별 쿼리를 실제와 유사한 데이터 분포로 실행한다. 평균 시간뿐 아니라 상위 지연, rows examined, 임시 테이블과 정렬의 변화를 비교한다. EXPLAIN ANALYZE는 실제 실행한다는 점을 고려해 안전한 시험 환경에서 사용한다.
  • 혼합 버전 복제: replica를 먼저 검증하고 source를 나중에 전환하는 순서를 기본으로 검토한다. 혼합 기간에는 구버전이 해석하지 못할 수 있는 새 binlog 기능을 성급히 켜지 않는다.
  • 백업·모니터링: 물리 백업 도구의 지원 조합, 로그 파서, Performance Schema 객체 및 계측 이름을 확인한다. 서버가 정상인데 수집기가 깨져 장애를 놓치는 경우도 회귀다.
  • 설정 보존: 전역값뿐 아니라 세션 초기화 SQL, 영속화 변수, 플러그인 로딩, 인증서를 비교한다. 이전 파일을 무조건 덮어쓰거나 새 기본값을 모두 받아들이는 두 극단을 피한다.

비교 대상의 데이터, 동시 접속 수, 실행 시간대와 캐시 조건을 최대한 맞춘다. 백업이나 배치가 한쪽에서만 돌았다면 관측된 지연 차이를 버전 효과로 단정할 수 없다. 통계 재수집도 실행 계획을 바꾸므로 업그레이드와 동시에 무조건 모든 테이블에 수행하기보다 대상과 목적을 정한다.

8. Aurora MySQL에서는 관리형 전환 경로로 다시 설계한다

Aurora MySQL version 2와 version 3의 전환은 Community MySQL의 바이너리 교체 절차를 그대로 실행하는 작업이 아니다. 대상 클러스터의 지원 경로를 확인하고 in-place upgrade, Blue/Green Deployment, snapshot restore 중 가능한 방식을 선택한다. 지원 여부는 엔진 버전과 클러스터 구성에 따라 달라진다.

AWS 공식 절차에서 in-place major upgrade는 클러스터가 중단되는 동안 정상 종료, rollback·undo purge 등의 작업을 수행하며, 스키마와 부하 특성에 따라 시간이 달라질 수 있다. 같은 인스턴스 크기라는 이유만으로 중단 시간을 고정값으로 계산하지 않는다. 운영과 유사한 복제본·clone에서 사전 검사와 리허설을 수행하고 precheck 로그의 오류·경고를 검토한다.

목표 엔진 계열에 맞는 cluster/DB parameter group, 확장 기능, 모니터링, 외부 binlog 연동, 접속 드라이버를 함께 확인한다. Snapshot restore를 AWS CLI/API로 수행하는 경로에서는 복원 클러스터에 writer DB instance를 별도로 생성해야 하는 절차도 놓치지 않는다.

In-place 전환이 endpoint를 보존하더라도 기존 연결이 유지된다는 뜻은 아니다. 연결 풀의 실패 감지와 재연결을 시험한다. 별도 클러스터 전환이면 endpoint 변경과 DNS 캐시까지 검증한다. Blue/Green 전환도 새 환경에서 쓰기를 시작한 이후 구환경으로 자동 역동기화되는 복구 장치로 해석하지 않는다. 이 글에서는 실제 Aurora 전환이나 다운타임을 측정하지 않았다.

9. 실행 승인과 완료 판정 체크리스트

전환 전

전환 중

전환 후

10. 정리

업그레이드의 핵심은 버전 번호를 올리는 것이 아니라, 지원 경로·데이터 의미·성능·실패 복구를 한 번의 변경 계약으로 묶는 것이다. 5.7에서 8.0으로 이동할 때는 딕셔너리와 호환성 경계가 중심이고, 8.0 minor upgrade에서는 누적 변경과 실제 쿼리 회귀가 중심이다.

검사 도구는 시작 조건을 좁혀 주지만 완료를 선언해 주지는 않는다. 후속 고가용성 설계에서도 같은 원칙을 적용한다. 새 writer를 만들 수 있다는 사실과, 데이터 손실 없이 안전하게 전환할 수 있다는 사실은 서로 다른 검증 항목이다.

참고 문서