mysql8 升级注意事项
- 升级不可逆(即不支持降级),只能通过还原升级前的数据备份实现降级
- 支持从MySQL 5.7升级到8.0,但不支持从非GA版本的MySQL 5.7升级
- 建议先升级到最新版本,然后再升级到下一版本。
- 例如,在升级到MySQL 8.0之前,先升级到最新的MySQL 5.7版本。
- 不支持跳过大版本的升级。例如,不支持直接从MySQL 5.6升级到8.0
- 不支持非GA版本软件升级
升级底层变更细节
-
更新mysql模式中的表对象
- 数据字典表:用于存储数据库对象元数据
- 系统表(即剩余的非数据字典表):用于其他操作目的
-
更新其它模式中内置对象
- performance_schema,INFORMATION_SCHEMA,sys 和 ndbinfo
- 用户模式
升级步骤
更新数据字典
- 模式中的数据字典表
mysql
。如果实际数据字典版本低于当前预期版本,则服务器会创建具有更新定义的数据字典表,将持久化的元数据复制到新表中,用新表原子替换旧表,然后重新初始化数据字典。 - performance_schema,
INFORMATION_SCHEMA
和ndbinfo
服务器升级
此步骤包括所有其他升级任务。如果现有MySQL安装的服务器版本低于新安装的MySQL版本的服务器版本,则其他所有内容都必须升级
- 模式中的系统表
mysql
(其余的非数据字典表)。 sys
schema- 用户架构
从 MySQL 8.0.16 开始,此步骤的职责的变更
-
在MySQL 8.0.16之前,需要手动调用mysql_upgrade工具升级performance_schema, INFORMATION_SCHEMA
-
从MySQL 8.0.16开始,mysqld 工具自动完成由之前的mysql_upgrade工具处理的所有任务
- 不再需要运行 mysql_upgrade,且不建议使用 mysql_upgrade
- 从MySQL 8.0.16开始,由
mysqld --upgrade
选项控制服务器在启动时是否以及如何执行自动升级- 不带--upgrade 选项或带 --upgrade=AUTO:Server启动时会尝试升级数据字典表和用户表
- --upgrade=NONE:Server启动时不会执行任何的升级动作。但是当必须要升级数据字典时,Server将会异常退出并抛出错误
- --upgrade=MINIMAL:Server启动时仅仅尝试执行数据字典的升级,其他的系统表、用户表等不会进行升级。这个选项和之前老的升级方式相同,必须再次使用mysql_upgrade 工具执行剩下的升级过程。然后需要再次重启Server。
- --upgrade=FORCE:Server启动时强制执行升级过程。使用该选项启动时需要更长的时间检查所有的对象。
mysql_upgrade 选项和mysqld 选项 类似等效命令
mysql_upgrade选项 | mysqld 选项 |
---|---|
--skip-sys-schema | --upgrade=NONE 或者 --upgrade=MINIMAL |
--upgrade-system-tables | --upgrade=NONE 或者 --upgrade=MINIMAL |
--force | --upgrade=FORCE |
升级前准备
不可以存在以下问题
- 不得有使用过时数据类型或功能的表
- 不能有孤立
.frm
文件 - 触发器不能有空定义者或无效环境
检查命令
${MYSQL_HOME}/bin/mysqlcheck -u root -p --all-databases --check-upgrade
不得有使用不具有本机分区支持的存储引擎的分区表
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE ENGINE NOT IN ('innodb', 'ndbcluster')
AND CREATE_OPTIONS LIKE '%partitioned%';
查询结果的任何表都必须更改为使用 InnoDB
或不分区。
要将表存储引擎更改为InnoDB
ALTER TABLE table_name ENGINE = INNODB;
要使分区表成为非分区表
ALTER TABLE table_name REMOVE PARTITIONING;
将MyISAM
表转换为的信息InnoDB
MySQL 5.7mysql
系统数据库中的表不得 与MySQL 8.0数据字典使用的表同名
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE LOWER(TABLE_SCHEMA) = 'mysql'
and LOWER(TABLE_NAME) IN
(
'catalogs',
'character_sets',
'check_constraints',
'collations',
'column_statistics',
'column_type_elements',
'columns',
'dd_properties',
'events',
'foreign_key_column_usage',
'foreign_keys',
'index_column_usage',
'index_partitions',
'index_stats',
'indexes',
'parameter_type_elements',
'parameters',
'resource_groups',
'routines',
'schemata',
'st_spatial_reference_systems',
'table_partition_values',
'table_partitions',
'table_stats',
'tables',
'tablespace_files',
'tablespaces',
'triggers',
'view_routine_usage',
'view_table_usage'
);
查询结果中任何表都必须删除或重命名
不得有外键约束名称超过64个字符的表
查询标识约束名称太长的表
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);
对于约束名称超过64个字符的表,请删除该约束并将其添加回不超过64个字符的约束名称
sql_mode
系统变量 不得定义过时的SQL模式
不得有明确定义的列名超过64个字符的视图
-- 检查视图定义
SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS;
表或存储过程中的单个 ENUM
或SET
列元素的长度不得超过255个字符或1020个字节。
升级到MySQL 8.0.13或更高版本之前,共享InnoDB
表空间中不得存在任何表分区,共享表空间应包括系统表空间和常规表空间。
通过查询来标识共享表空间中的表分区 INFORMATION_SCHEMA
- 从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';
- 从早期的MySQL 8.0版本升级
SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_TABLES
WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single';
使用以下命令将表分区从共享表空间移动到每个表文件表空间
ALTER TABLE table_name REORGANIZE PARTITION partition_name
INTO (partition_definition TABLESPACE=innodb_file_per_table);
MySQL 8.0.12或更低版本中不得有使用子句ASC
或 DESC
限定符的查询和存储程序定义GROUP BY
如果打算lower_case_table_names在升级时将设置更改 为1,请在升级之前确保schema和表名均为小写
检查包含大写字符的架构和表名称
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME != LOWER(TABLE_NAME) AND TABLE_TYPE = 'BASE TABLE';
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME != LOWER(SCHEMA_NAME);
不建议升级中修改 lower_case_table_names 的设置
从MySQL 8.0.19开始,如果lower_case_table_names=1
,升级过程会检查表名和模式名,以确保所有字符均为小写。如果发现表或架构名称包含大写字符,则升级过程将失败并显示错误。
升级失败处理
如果由于上述任何问题升级到MySQL 8.0失败,则服务器会将所有更改都还原到数据目录。在这种情况下,请删除所有重做日志文件,然后在现有数据目录上重新启动MySQL 5.7服务器以解决错误。重做日志文件(ib_logfile*
)默认位于MySQL数据目录中。修复错误之后,请执行缓慢关机(通过设置 innodb_fast_shutdown=0
),然后再次尝试升级。
升级过程
MySQL二进制包软件升级
就地升级方式
检查未提交的XA事务
XA RECOVER;
从MySQL 5.7.11或更早版本升级到MySQL 8.0,并且有加密的 InnoDB
表空间
通过执行以下语句来旋转密钥环主密钥
ALTER INSTANCE ROTATE INNODB MASTER KEY;
快速或慢速关闭服务
通过快速关闭或缓慢关闭,可以InnoDB
将其撤消日志和数据文件保持在可以处理的状态,以防两个版本之间的文件格式不同。
SET GLOBAL innodb_fast_shutdown = 1; -- fast shutdown
SET GLOBAL innodb_fast_shutdown = 0; -- slow shutdown
mysqladmin -uroot -p --innodb_fast_shutdown=0 shutdown
升级MySQL二进制文件或软件包
# 1. 删除软连接
unlink mysql
# 2. 解压二进制包新版本软件
tar -xf mysql-8.0.18-linux-glibc2.12-x86_64.tar.xz -C /usr/local
# 3. 创建软链接
ln -s /usr/local/mysql-8.0.18-linux-glibc2.12-x86_64 mysql
# 4. 修改软件目录用户及用户组
chow -R mysql:mysql /usr/local/mysql-8.0.18-linux-glibc2.12-x86_64
使用现有数据目录启动MySQL 8.0服务
- 8.0.16 开始
mysqld_safe --user=mysql --datadir=/path/to/existing-datadir &
-
在MySQL 8.0.16之前
mysql_upgrade -u root -p mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to/existing-datadir &
如果存在加密的InnoDB
表空间
使用 mysqld --early-plugin-load="myplug1=myplug1.so;myplug2=myplug2.so" 选项加载密钥环插件