먹고 살려고 공부

[Real MySQL 8.0]MySQL 8.0과 Docker - 업그레이드 (5.7에서 8.X으로) 본문

Database/MySQL

[Real MySQL 8.0]MySQL 8.0과 Docker - 업그레이드 (5.7에서 8.X으로)

10104 2025. 1. 17. 10:05

from MySQL 5.7 to MySQL 8.0

MySQL 공식 문서에서 도커로 버전을 업그레이드 하는 방법이 작성되어있다.

https://dev.mysql.com/doc/refman/8.4/en/docker-mysql-getting-started.html#docker-upgrading

 

MySQL :: MySQL 8.4 Reference Manual :: 2.5.6.1 Basic Steps for MySQL Server Deployment with Docker

2.5.6.1 Basic Steps for MySQL Server Deployment with Docker Warning The MySQL Docker images maintained by the MySQL team are built specifically for Linux platforms. Other platforms are not supported, and users using these MySQL Docker images on them are d

dev.mysql.com

 

 

MySQL 서버 업그레이드 종류

MySQL 서버 업그레이드에는 두 가지 방법이 있다.

  1. MySQL 서버의 데이터 파일을 그대로 두고 업그레이하는 방법 - 인플레이스 업그레이드(In-Place Upgrade)
  2. mysqldump 도구 등을 이용해 MySQL 서버의 데이터를 SQL 문장이나 텍스트 파일로 덤프한 후, 새로 업그레이드된 버전의 MySQL 서버에서 덤프된 데이터를 적재하는 방법 - 논리적 업그레이드(Logical Upgrade)

인플레이스 업그레이드는 여러 가지 제약 사항이 있지만 업그레이드 시간을 크게 단축할 수 있다. 
논리적 업그레이드는 버전 간 제약 사항이 거의 없지만 업그레이드 시간이 많이 소요될 수 있다.

 

 

인플레이스 업그레이드

인플레이스 업그레이드는 마이너(패치) 버전 간 업그레이드와 메이저 버전 간 업그레이드 둘로 나뉜다.

  • 동일 메이저에서 마이너 버전간 업그레이드는 대부분 데이터 파일의 변경 없이 진행된다. 여러 버전을 건너뛰어서 업그레이드 하는 것도 허용된다.
  • 메이저간 업그레이드는 대부분 데이터 파일의 변경이 필요하기 때문에 직전 버전에서만 업그레이드가 허용된다. 직전 버전의 데이터 파일과 로그 포맷만 인식하도록 구현되어있다.

MySQL5.5 -> MySQL5.6 (O)
MySQL5.5 -> MySQL5.7 (X) => 이럴 경우 mysqldump 프로그램을 이용한 논리적 업그레이드가 더 나을 수 있다.

메이저 버전 업그레이드가 특정 마이너 버전에서만 가능할 수 있다. 항상 메이저 버전을 업그레이드 할 때에는 MySQL 서버의 메뉴얼을 정독하자

 

 

MySQL 8.0 업그레이드

5.7에서 8.0으로 업그레이드 시 고려할 점

  • 사용자 인증 방식 변경
    Caching SHA-2 Authentication 인증 방식이 기본 인증 방식으로 바뀌었다.(기존 5.7의 경우 Native Authentication 인증 방식이 default 만약 Native Authentication을 계속 사용하고 싶을 경우 authentication-plugin=mysql_native_password)
  • MySQL 8.0과의 호환성 체크
    손상된 frm 파일이나 호환되지 않는 데이터 타입 또는 함수가 있는 지 mysqlcheck 유틸리티를 이용해 확인해야한다.
  • 외래키 이름의 길이
    8.0 버전부터는 외래키의 이름이 64글자로 제한된다.
  • 인덱스 힌트
    5.X 버전에서 사용된 인덱스 힌트는 8.0 버전에서 오히려 성능 저하를 유발할 수 있다.
  • GROUP BY에 사용된 정렬 옵션:
    MySQL 5.x 버전에서 GROUP BY 절의 칼럼 뒤에 'ASC'나 'DESC'를 사용(GROUP BY field_name [ASC|DESC] 포맷)하고 있다면 제거하거나 다른 방식으로 변경 - 8.0 이전 버전에서는 GROUP BY 뒤에 암묵적으로 ORDER BY없이 ASC, DESC가 가능했지만, 8.0 버전부터는 GROUP BY 뒤에 ASC, DESC와 같은 정렬 작업이 필요하면 ORDER BY가 반드시 필요하다.
  • 파티션을 위한 공용 테이블스페이스
    8.X 버전에서는 파티션의 각 테이블스페이스를 공용 테이블스페이스에 저장할 수 없다. 파티션의 테이블스페이스가 공용 테이블스페이스에 저장되어있는 지 확인, 있을 경우 ALTER TABLE ... REORGANIZE 명령을 실행하여 개별 테이블스페이스를 사용하도록 변경

 

참고:

https://dev.mysql.com/doc/refman/8.0/en/upgrading.html

 

MySQL :: MySQL 8.0 Reference Manual :: 3 Upgrading MySQL

MySQL 8.0 Reference Manual  /  Upgrading MySQL PREV   HOME   UP   NEXT

dev.mysql.com

https://dev.mysql.com/blog-archive/inplace-upgrade-from-mysql-5-7-to-mysql-8-0/

 

MySQL :: INPLACE upgrade from MySQL 5.7 to MySQL 8.0

MySQL 8.0 General Availability was announced in April and it comes with a host of new features. The overview about the new features and improvements made in MySQL 8.0 can be found in the following blog. The server can be upgraded by performing either an IN

dev.mysql.com

 

 

몇 가지 언급했던 내용을 실행하거나 체크하는 명령은 다음과 같다.

 

# mysqlcheck 유틸리티
root@8e3ce86d5d64:/realmysql8# mysqlcheck -uroot -p --all-databases --check-upgrade
Enter password:
employees.departments                              OK
employees.dept_emp                                 OK
employees.dept_manager                             OK
employees.employee_docs                            OK
employees.employee_name                            OK
employees.employees                                OK
employees.employees_comp4k                         OK
employees.employees_comp8k                         OK
employees.salaries                                 OK
employees.tb_dual                                  OK
employees.titles                                   OK
mysql.columns_priv                                 OK
mysql.component                                    OK
mysql.db                                           OK
mysql.default_roles                                OK
mysql.engine_cost                                  OK
mysql.func                                         OK
mysql.general_log                                  OK
mysql.global_grants                                OK
mysql.gtid_executed                                OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.ndb_binlog_index                             OK
mysql.password_history                             OK
mysql.plugin                                       OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.replication_asynchronous_connection_failover OK
mysql.replication_asynchronous_connection_failover_managed OK
mysql.replication_group_configuration_version      OK
mysql.replication_group_member_actions             OK
mysql.role_edges                                   OK
mysql.server_cost                                  OK
mysql.servers                                      OK
mysql.slave_master_info                            OK
mysql.slave_relay_log_info                         OK
mysql.slave_worker_info                            OK
mysql.slow_log                                     OK
mysql.tables_priv                                  OK
mysql.time_zone                                    OK
mysql.time_zone_leap_second                        OK
mysql.time_zone_name                               OK
mysql.time_zone_transition                         OK
mysql.time_zone_transition_type                    OK
mysql.user                                         OK
sys.sys_config                                     OK

 

MySQL 5.7 버전에서 체크해야할 것

-- // 외래키 이름의 길이 체크 - MySQL 5.7
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.TABLES
WHERE TABLE_NAME IN
	(SELECT LEFT(SUBSTR(ID, INSTR(ID, '/')+1),
		INSTR(SUBSTR(ID,INSTR(ID,'/')+1),'_ibfk_')-1)
		FROM information_schema.INNODB_SYS_FOREIGN
		WHERE LENGTH(SUBSTR(ID,INSTR(ID,'/')+1))>64);
-- // 공용 테이블스페이스에 저장된 파티션이 있는지 체크 - MySQL 5.7
SELECT DISTINCT NAME, SPACE, SPACE_TYPE
	FROM information_schema.INNODB_SYS_TABLES
	WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE '%Single%';

 

 

바뀐 부분 (5.7 -> 8.0)

MySQL 5.7에서 MySQL 8.0으로 바뀌면서 서버 내부적으로도 변화가 일어났는데, 그 중 두 개의 포맷이 완전히 바뀌었다.

  • 시스템 테이블의 정보
  • 데이터 딕셔너리(Data Dictionary) 정보
    5.7 버전까지는 데이터 딕셔너리 정보는 FRM 확장자를 가진 파일로 별도로 보관됐었다. 8.0 버전부터는 데이터 딕셔너리 정보는 InnoDB 테이블(트랜잭션 지원)로 저장되도록 개선되었다.
    8.0 버전부터는 딕셔너리 데이터의 버전 간 호환성 관리를 위해 테이블이 생성될 때 사용된 MySQL 서버의 버전 정보도 함께 기록한다.

서버 업그레이드 MySQL 서버의 시스템 데이터베이스(performance_schema와 information_schema, 그리고 mysql 데이터베이스)의 테이블 구조를 MySQL 8.0 버전에 맞게 변경한다.

 

from MySQL 5.7 to MySQL ~8.0.15
데이터 딕셔너리 업그레이드 작업 - mysqld 실행

서버 업그레이드 - mysql_upgrade(8.0.16버전부터는 사용하지 않는다) 프로그램 실행

  1. MySQL 셧다운
  2. MySQL5.7 프로그램 삭제
  3. MySQL 8.0 프로그램 설치
  4. MySQL 8.0 서버(mysqld) 시작(MySQL 서버가 데이터 딕셔너리 업그레이드를 자동 실행)
  5. mysql_upgrade 프로그램 실행(mysql_upgrade 프로그램이 시스템 테이블의 구조를 MySQL 8.0에 맞게 변경)

 

from MySQL 5.7 to MySQL 8.0.16~

모든 업그레이드작업 - mysqld 실행

  1. MySQL 셧다운
  2. MySQL 5.7 프로그램 삭제
  3. MySQL 8.0 프로그램 설치
  4. MySQL 8.0 서버(mysqld) 시작(MySQL 서버가 데이터 딕셔너리 업그레이드를 실행 후, 시스템 테이블 구조를 MySQL 8.0에 맞게 변환)