MySQL8.0:升级对应用有哪些影响?
很多公司对于 MySQL5.7 升级到 MySQL8.0 都会顾虑应用是否会受到影响,其实这个主要看8.0相比5.7有何变化,手册上关于升级那一章节对这些方面做了详细的描述:https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html。我在此基础上以自己的理解进行了一些整理,主要分为几部分:数据字典的变更、默认密码验证插件变为 caching_sha2_password、配置变更、Server 的变更、InnoDB 的变更、SQL 的变更。
数据字典的变更
MySQL 8.0 将数据库元信息都存放于InnoDB存储引擎表中,在之前版本的MySQL中,数据字典不仅仅存放于特定的存储引擎表中,还存放于元数据文件、非事务性存储引擎表中。
数据字典表是不可见的,不会被 show tables、INFORMATION_SCHEMA.TABLES 显示出来。不过可以通过 INFORMATION_SCHEMA 库中的一些视图进行查询,当通过 INFORMATION_SCHEMA 查询表的统计信息时,默认使用缓存的表统计信息,速度会很快。而 8.0 以前,由于数据字典部分还存放于元数据文件中,例如读取数据库表结构信息,底层其实是读取.frm文件来获得,相对较慢。
大概列几点变化:
-
innodb_read_only 对所有存储引擎生效。在8.0之前版本中,innodb_read_only参数可以阻止对InnoDB存储引擎表的create和drop等更新操作。但是在MySQL8.0中,开启innodb_read_only参数阻止了所有存储引擎的这些操作。create或者drop表的操作都需要更新数据字典表,8.0中这个数据字典表都改为了InnoDB存储引擎,所以对于数据字典表的更新会失败,从而导致各存储引擎create和drop表失败。同样的像ANALYZE TABLE和ALTER TABLE tbl_name ENGINE=engine_name这种操作也会失败,因为这些操作都要去更新数据字典表;
-
因为数据字典表改用 InnoDB 引擎,DDL支持原子性;
-
8.0开始,mysqldump/mysqlpump 只会导出 mysql 库中的非数据字典表(数据字典表内容参考:https://dev.mysql.com/doc/refman/8.0/en/system-schema.html#system-schema-data-dictionary-tables)
-
8.0之前版本当使用--all-databases参数导出数据的时候,不加--routines和--events选项也可以导出触发器、存储过程等信息,因为这些信息都存放于proc和event表中,导出所有表即可导出这些信息。但是在8.0中,proc表和event表都不再使用,并且定义触发器、存储过程的数据字典表不会被导出,所以在8.0中使用mysqldump、mysqlpump导出数据的时候,如果需要导出触发器、存储过程等内容,一定需要加上--routines和--events选项;
-
8.0之前版本中--routines选项导出的时候,备份账户需要有proc表的SELECT权限,在8.0中需要对所有表的SELECT权限;
-
8.0之前版本中,导出触发器、存储过程可以同时导出触发器、存储过程的创建和修改的时间戳,8.0中不再支持。
数据字典变更对于其使用的影响详见:https://dev.mysql.com/doc/refman/8.0/en/data-dictionary-usage-differences.html
默认密码验证插件变为 caching_sha2_password
caching_sha2_password 比 sha256_password 提供更安全的密码加密和更好的性能,MySQL 8.0 将默认的密码验证插件从 sha256_password 变成了 caching_sha2_password。
影响:如果客户端和连接器版本不支持 caching_sha2_password 验证方式,将无法连接到 MySQL server,需要升级客户端和连接器的版本。
配置变更
1. 分区功能由存储引擎自己处理,MySQL server 不再处理分区,只有 InnoDB 和 NDB 引擎支持分区功能。
事实上,在MySQL5.7 上创建 myisam 的分区表也会有 warning 提示。通过以下SQL检查有没有不合格的分区表:
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE NOT IN ('innodb', 'ndbcluster') AND CREATE_OPTIONS LIKE '%partitioned%';
2. 默认字符编码由 latin1 变为 utf8mb4;
3. MySQL8.0.11之后,启动 MySQL server 时,lower_case_table_names 的设置必须和初始化时一样。因为各种数据字典表字段使用的归类基于在初始化时的 lower_case_table_names 设置,并且使用不同的设置重新启动 MySQL 会导致标识符排序和比较的不一致;
4. 部分参数新增、删除、修改,详见:https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html
Server 的变更
1. MySQL 8.0.11 SQL_MODE 删除了 NO_AUTO_CREATE_USER 选项,注意5.7.24版本之前 mysqldump 备份产生的 sql 文件头部会做这个设置,会导致导入到 8.0 时报错;
2. MySQL 8.0.11 删除了不推荐使用的兼容性SQL Mode:DB2,MAXDB,MSSQL,MySQL323,MySQL40,ORACLE,POSTGRESQL,NO_FIELD_OPTIONS,NO_KEY_OPTIONS,NO_TABLE_OPTIONS。从5.7到8.0的复制场景中,如果语句使用到废弃的SQL Mode会导致复制异常;
3. In-place 方式升级到 MySQL 8.0.3或更高版本时,自动给具有 RELOAD 权限的用户授予 BACKUP_ADMIN 权限;
4. 复制运行时限制了 binlog_format 的在线修改。
InnoDB 的变更
1. 由于数据字典表的变更,INFORMATION_SCHEMA 中的一些视图重命名了,具体见:https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-innodb-changes
2. zlib 库从1.2.3版本升级到1.2.11版本,主要影响 InnoDB 表的压缩功能;
3. undo log 默认就保存在两个独立的 undo 表空间中,不再保存在系统表空间中;
4. MySQL8.0.17 开始,CREATE TABLESPACE ... ADD DATAFILE子句不允许循环目录引用。 例如循环目录引用(/../)是不允许的。
SQL 的变更
1. 从MySQL 8.0.13开始,删除了 GROUP BY 子句不推荐使用的 ASC 或 DESC 子句。先前依赖于 GROUP BY 排序的查询所产生的结果可能与以前的 MySQL 版本不同,要产生给定的排序顺序,需要写 ORDER BY 子句;
2. 保留关键字发生了一些变化,可能在 MySQL8.0 以前可以使用,8.0之后不可以使用。详见:https://dev.mysql.com/doc/refman/8.0/en/keywords.html