将MySQL 5.7升级到8.0版本的实践经验

图片

我们最近将服务器从MySQL 5.7升级到8.0。

让我们不在本文讨论范围之内,为什么以及在MySQL 8.0中出现了哪些新的包子,但是我们将讨论在升级过程中遇到的困难。

首先,在更新之前,有必要查看更改列表并更正您的配置文件。

至少删除了以下选项:
innodb_file_format,innodb_file_format_check,innodb_file_format_max,innodb_large_prefix
query_cache_limit,query_cache_min_res_unit,query_cache_size,query_cache_type,query_cache_wlock_invalidate。

特别是在sql_mode参数中,删除了NO_AUTO_CREATE_USER-这尤其重要,因为 在MySQL 5.7中,默认情况下已将其打开。

Percona具有就地升级的说明。 在一般情况下,您可以按照它进行操作,但是,我们仅以此方式更新了一个集群;对于其他情况,尝试对此集群进行更新的尝试失败,并显示类似的错误:

2019-06-22T05:04:18.510888Z 1 [ERROR] [MY-011014] [Server] Found partially upgraded DD. Aborting upgrade and deleting all DD tables. Start the upgrade process again. 2019-06-22T05:04:23.115018Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed. 2019-06-22T05:04:23.115655Z 0 [ERROR] [MY-010119] [Server] Aborting 

因此,我们通过引发一个新的空实例并从以前的版本还原数据库转储来更新剩余的群集。

为此,首先,需要数据库转储。 在这里,危险#1在等待-以标准方式进行的转储:

 mysqldump -u root -p --hex-blob --default-character-set=utf8mb4 --all-databases --triggers --routines --events > dump.sql 

它不会恢复并给出错误:

 ERROR 3554 (HY000) at line 15915: Access to system table 'mysql.innodb_index_stats' is rejected. 

该说明位于MySQL bugtracker中 (状态为Not a bug :),还提供了有关如何转储它以便恢复它的建议:

 mysqldump -u root -p --hex-blob --default-character-set=utf8mb4 --all-databases --triggers --routines --events --ignore-table=mysql.innodb_index_stats --ignore-table=mysql.innodb_table_stats > dump.sql 

但是,当尝试使用此类转储时,如果其中有触发器(并且我们有触发器),则可能会以这种错误的形式出现危险2:

 ERROR 1231 (42000) at line 54: Variable 'sql_mode' can't be set to the value of 'NO_AUTO_CREATE_USER' 

这样做的原因是因为MySQL使用sql_mode作为触发器,即:MySQL在创建触发器时将sql_mode值保存为触发器,然后始终使用该值执行它。 并相应地将此值保存在转储中。

帮助说明:
dev.mysql.com/doc/refman/8.0/en/create-trigger.html
创建触发器时,MySQL将存储有效的sql_mode系统变量设置,并且始终在该设置生效的情况下执行触发器主体,而不管触发器开始执行时当前的服务器SQL模式如何。

我们该怎么办? 我们只是从完成的转储中剪切了NO_AUTO_CREATE_USER。 类似的命令:

 sed "s/50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER/50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO/g" dump.sql > dump2.sql 

此后,转储已成功还原,但是危险#3等待着我们(这是预料之中的事实)-系统表已从5.7版还原到状态,并且日志中存在以下错误:

 [ERROR] [MY-013143] [Server] Column count of mysql.user is wrong. Expected 51, found 45. The table is probably corrupted 

从以前版本的经验来看,这可以通过运行mysql_upgrade来解决-但从8.0.16版本开始-这样做不起作用,因为 mysql_upgrade被声明为已弃用,不执行任何操作。

现在,要更新系统表,您必须使用选项upgrade = FORCE启动MySQL。

在新的ubuntu上,可以按以下步骤进行:

 systemctl set-environment MYSQLD_OPTS="--upgrade=FORCE" 

然后重启MySQL。 好吧,在成功更新之后,将其删除:

 systemctl unset-environment MYSQLD_OPTS 

Source: https://habr.com/ru/post/zh-CN476852/


All Articles