赞
踩
事出必有因,在这个月的某个项目中,我们面临了一项重要任务,即每年一次的等保测评整改。这次测评的重点是Mysql的一些高危漏洞,客户要求我们无论如何必须解决这些漏洞。尽管我们感到无奈,但为了满足客户的要求,我们只能硬着头皮进行升级。而碰巧的是,Mysql5.7
在10月
份停止了更新,借着这次机会,我们决定研究一下Mysql5.7
升级到Mysql8.0
的过程。在本文的最后,我将分享一些在这次升级过程中遇到的问题。
升级需求:将5.7.43
升级到8.0.34
, 升级方式 in-place
升级【关闭现有版本MySQL,将二进制或包替换成新版本并在现有数据目录上启动MySQL并执行升级任务的方式,称为in-place
升级】
原版本 | 5.7.43 | CentOS Linux release 7.9.2009 |
新版本 | 8.0.34 | CentOS Linux release 7.9.2009 |
以下Mysql 生命周期-内容来自于互联网
关于数据库版本升级,一直都是热议话题,对于升级的缘由各家也有所不同,有业务驱动的,有DBA自发驱动的,有规划导向也有方向指引的……抛开各种原因,当升级这个决定落下来的时候,对于DBA手头的几百几千套数据库来说,就好比是一场动物大迁徙,满满的画面感。
从Oracle发布的版本生命周期规划可以看到,Mysql5.7
已经走到了生命周期的终点,意味着后续将不再为Mysql5.7
提供官方更新、错误修复或安全补丁。
阿里云和AWS都在官方公布了版本支持计划,Mysql5.7
版本已经开始了倒计时。
默认字符集由latin1变为utf8mb4。
MyISAM系统表全部换成InnoDB表。
JSON特性增强。
支持不可见索引,支持直方图。
sql_mode参数默认值变化。
默认密码策略变更。
新增角色管理。
支持窗口函数,支持Hash join。
支持从MySQL5.7
升级到MySQL8.0
,注意仅支持GA版本之间的升级。
不支持跨大版本的升级,如从5.6
升级到8.0
是不支持的。
建议升级大版本前先升级到当前版本的最近小版本,如5.7
先升级到5.7.43
后再升级到8.0
。
做好充足的备份!数据无价!!!
在执行升级操作前需要做一些检查工作,确认准备工作是否就绪,避免升级过程中出现异常。可以使用
MySQL Shell
使用util.checkForServerUpgrade
进行检查,返回内容包括不符合迁移要求的问题,error的问题需要迁移前修改。
Mysql-shell 下载地址:https://dev.mysql.com/downloads/shell/
image-20231026094319303
选择 Archives ,查询更多版本
image-20231026094455783
选择当前最新的版本8.0.34,x84,64-bit
下载地址:https://downloads.mysql.com/archives/get/p/43/file/mysql-shell-8.0.34-linux-glibc2.12-x86-64bit.tar.gz
image-20231026101051586
- #下载包
- [root@srebro.cn ~]# wget https://downloads.mysql.com/archives/get/p/43/file/mysql-shell-8.0.34-linux-glibc2.12-x86-64bit.tar.gz -C /root
-
- [root@srebro.cn ~]# tar -xf mysql-shell-8.0.34-linux-glibc2.12-x86-64bit.tar.gz
-
- [root@srebro.cn ~]# cd /root/mysql-shell-8.0.34-linux-glibc2.12-x86-64bit/bin
-
-
- [root@srebro.cn bin]# ./mysqlsh -uroot -p -S /tmp/mysql.sock -e "util.checkForServerUpgrade()" > util.checkForServerUpgrade.log
输出报告
- The MySQL server at /tmp%2Fmysql.sock, version 5.7.39-log - MySQL Community
- Server (GPL), will now be checked for compatibility issues for upgrade to MySQL
- 8.0.34...
-
- 1) Usage of old temporal type
- No issues found
-
- 2) MySQL 8.0 syntax check for routine-like objects
- No issues found
-
- 3) Usage of db objects with names conflicting with new reserved keywords
- No issues found
-
- 4) Usage of utf8mb3 charset
- Warning: The following objects use the utf8mb3 character set. It is
- recommended to convert them to use utf8mb4 instead, for improved Unicode
- support.
- More information:
- https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html
-
- mysql - schema's default character set: utf8
- test - schema's default character set: utf8
-
- 5) Table names in the mysql schema conflicting with new tables in 8.0
- No issues found
-
- 6) Partitioned tables using engines with non native partitioning
- No issues found
-
- 7) Foreign key constraint names longer than 64 characters
- No issues found
-
- 8) Usage of obsolete MAXDB sql_mode flag
- No issues found
-
- 9) Usage of obsolete sql_mode flags
- Notice: The following DB objects have obsolete options persisted for
- sql_mode, which will be cleared during upgrade to 8.0.
- More information:
- https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html#mysql-nutshell-removals
-
- global system variable sql_mode - defined using obsolete NO_AUTO_CREATE_USER
- option
-
- 10) ENUM/SET column definitions containing elements longer than 255 characters
- No issues found
-
- 11) Usage of partitioned tables in shared tablespaces
- No issues found
-
- 12) Circular directory references in tablespace data file paths
- No issues found
-
- 13) Usage of removed functions
- No issues found
-
- 14) Usage of removed GROUP BY ASC/DESC syntax
- No issues found
-
- 15) Removed system variables for error logging to the system log configuration
- To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
- More information:
- https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-13.html#mysqld-8-0-13-logging
-
- 16) Removed system variables
- To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
- More information:
- https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html#optvars-removed
-
- 17) System variables with new default values
- To run this check requires full path to MySQL server configuration file to be specified at 'configPath' key of options dictionary
- More information:
- https://mysqlserverteam.com/new-defaults-in-mysql-8-0/
-
- 18) Zero Date, Datetime, and Timestamp values
- No issues found
-
- 19) Schema inconsistencies resulting from file removal or corruption
- No issues found
-
- 20) Tables recognized by InnoDB that belong to a different engine
- No issues found
-
- 21) Issues reported by 'check table x for upgrade' command
- No issues found
-
- 22) New default authentication plugin considerations
- Warning: The new default authentication plugin 'caching_sha2_password' offers
- more secure password hashing than previously used 'mysql_native_password'
- (and consequent improved client connection authentication). However, it also
- has compatibility implications that may affect existing MySQL installations.
- If your MySQL installation must serve pre-8.0 clients and you encounter
- compatibility issues after upgrading, the simplest way to address those
- issues is to reconfigure the server to revert to the previous default
- authentication plugin (mysql_native_password). For example, use these lines
- in the server option file:
-
- [mysqld]
- default_authentication_plugin=mysql_native_password
-
- However, the setting should be viewed as temporary, not as a long term or
- permanent solution, because it causes new accounts created with the setting
- in effect to forego the improved authentication security.
- If you are using replication please take time to understand how the
- authentication plugin changes may impact you.
- More information:
- https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-compatibility-issues
- https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-replication
-
- 23) Columns which cannot have default values
- No issues found
-
- 24) Check for invalid table names and schema names used in 5.7
- No issues found
-
- 25) Check for orphaned routines in 5.7
- No issues found
-
- 26) Check for deprecated usage of single dollar signs in object names
- No issues found
-
- 27) Check for indexes that are too large to work on higher versions of MySQL
- Server than 5.7
- No issues found
-
- 28) Check for deprecated '.<table>' syntax used in routines.
- No issues found
-
- Errors: 0
- Warnings: 3
- Notices: 1
-
- NOTE: No fatal errors were found that would prevent an upgrade, but some potential issues were detected. Please ensure that the reported issues are not significant before upgrading.
-
-
从输出报告可以看出,升级检查器在
28
个方面进行了检查,最终得出3
个警告信息和1
个提示。
Usage of utf8mb3 charset 在 MySQL 8.0版本之前,默认字符集为latin1
,utf8
字符集指向的是utf8mb3
。从MySQL8.0
开始,数据库的默认编码将改为utf8mb4 ;为了避免新旧对象字符集不一致的情况,可以在配置文件将字符集和校验规则设置为旧版本的字符集和比较规则。
New default authentication plugin considerations,密码认证插件变更。为了避免连接问题,可以仍采用5.7的mysql_native_password
认证插件。
Usage of obsolete sql_mode flags:Mysq8.0
版本sql_mode不支持NO_AUTO_CREATE_USER
,要避免配置的sql_mode
中带有NO_AUTO_CREATE_USER
。
通过以上的例子,可以发现,MySQL Shell
提供的升级检查工具能够帮助我们检测版本兼容性,减轻升级工作负担。
which mysqldump
/home/application/mysql/app/bin/mysqldump# --routines 备份存储过程和函数;--set-gtid-purged=OFF: 禁用GTID(全局事务标识);xxx1,XXX2 表示库名,备份多个库 用空格做为间隔
/home/application/mysql/app/bin/mysqldump -uroot -p --routines --set-gtid-purged=OFF --single-transaction --databases XXX1 XXX2 > /root/all-database-20231026.sql
- # 进入原5.7 mysql命令行 正确关闭数据库
- [root@srebro.cn ~]# mysql -uroot -p'srebro'
-
- mysql> select version();
- +------------+
- | version() |
- +------------+
- | 5.7.43-log |
- +------------+
- 1 row in set (0.00 sec)
-
- mysql> show variables like 'innodb_fast_shutdown';
- +----------------------+-------+
- | Variable_name | Value |
- +----------------------+-------+
- | innodb_fast_shutdown | 1 |
- +----------------------+-------+
- 1 row in set (0.00 sec)
-
-
- # 确保数据都刷到硬盘上,更改成0
- InnoDB 关闭模式。
- 如果值为 0,InnoDB 会在关闭前进行缓慢关闭、完全清除和更改缓冲区合并。
- 如果值为 1(默认值),InnoDB 会在关闭时跳过这些操作,这个过程称为快速关闭。
- 如果值为 2,InnoDB 刷新其日志并冷关机,就好像 MySQL 崩溃了;没有提交的事务丢失,但崩溃恢复操作使下一次启动需要更长的时间。 在仍然缓冲大量数据的极端情况下,缓慢关闭可能需要几分钟甚至几小时。
-
- mysql> set global innodb_fast_shutdown=0;
- Query OK, 0 rows affected (0.00 sec)
-
-
-
- mysql> shutdown;
- Query OK, 0 rows affected (0.00 sec)
-
- mysql> exit
- Bye
-
- [root@cmdb ~]# ps -ef | grep mysql
- root 30990 30934 0 16:12 pts/0 00:00:00 grep --color=auto mysql
- --确认数据库状态为关闭状态
- [root@srebro.cn ~]# systemctl status mysqld
-
- --数据目录备份
- [root@srebro.cn ~]# cp -r /home/application/mysql/data /home/application/mysql/data_bak_`date +%F`
-
- --安装目录备份
- [root@srebro.cn ~]# cp -r /home/application/mysql/app/ /home/application/mysql/app_bak_`date +%F`
-
-
- --配置文件备份
- [root@srebro.cn ~]# cp /etc/my.cnf /etc/my.cnf_`date +%F`
image-20231030140413635
https://dev.mysql.com/downloads/
选择 Archives ,查询更多版本
image-20231026162331985
下载地址:https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.34-linux-glibc2.12-x86_64.tar.xz 选择mysql-8.0.34-linux-glibc2.12-x86_64.tar.xz
image-20231026162932517
- #执行以下步骤解压tar包:
- # 安装包上传至原安装包目录下 我的是/home/application/mysql
-
- [root@srebro.cn ~]# cd /home/application/mysql
- [root@srebro.cn mysql]# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.34-linux-glibc2.12-x86_64.tar.xz
-
- [root@srebro.cn mysql]# tar -xf mysql-8.0.34-linux-glibc2.12-x86_64.tar.xz
-
-
- # 文件夹重命名为mysql8
- [root@srebro.cn mysql]# mv mysql-8.0.34-linux-glibc2.12-x86_64 mysql8
-
- # 更改文件夹所属
- [root@srebro.cn mysql]# chown -Rf mysql:mysql /home/application/mysql/mysql8
-
- # 删除安装包
- [root@srebro.cn mysql]# rm -rf mysql-8.0.34-linux-glibc2.12-x86_64.tar.xz
-
因5.7版本与8.0版本参数有所不同,为了能顺利升级,我们需要更改部分配置参数。主要注意
sql_mode
、basedir
、密码认证插件
及字符集
设置,其他参数最好还是按照原5.7的来,不需要做调整。下面展示5.7
和8.0
的配置文件,注意备份原来配置文件
。
- [mysql]
- socket=/tmp/mysql.sock
- default-character-set=utf8
-
- [mysqld]
- user=mysql
- basedir=/home/application/mysql/app
- datadir=/home/application/mysql/data
- character_set_server=utf8
- collation-server=utf8_general_ci
-
- #日志时间
- log_timestamps=SYSTEM
-
- port=3306
- socket=/tmp/mysql.sock
-
- max_connections=1000
- max_allowed_packet=500M
- sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
-
-
- #慢日志
- long_query_time=3
- slow_query_log=ON
- slow_query_log_file=/home/application/mysql/slow_query.log
-
- #错误日志
- log-error=/home/application/mysql/mysql-error.log
-
-
-
- #binlog配置
- server_id=150
- log-bin=mysql-bin
- max_binlog_size = 100M
- binlog_format=row
- log_slave_updates
- expire_logs_days=7
-
- #只能用IP地址检查客户端的登录,不用主机名
- skip-name-resolve=1
- [mysql]
- socket=/tmp/mysql.sock
- default-character-set=utf8
-
- [mysqld]
- user=mysql
-
- #日志时间
- log_timestamps=SYSTEM
- port=3306
- socket=/tmp/mysql.sock
- max_connections=1000
- max_allowed_packet=500M
- #只能用IP地址检查客户端的登录,不用主机名
- skip-name-resolve=1
-
-
- #binlog配置
- server_id=150
- log-bin=mysql-bin
- max_binlog_size = 100M
- binlog_format=row
- log_slave_updates
- expire_logs_days=7
-
- #慢日志
- long_query_time=3
- slow_query_log=ON
- slow_query_log_file=/home/application/mysql/slow_query.log
-
- #错误日志
- log-error=/home/application/mysql/mysql-error.log
-
-
-
- #for8.0
- sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
- basedir=/home/application/mysql/mysql8
- datadir=/home/application/mysql/data
- character_set_server=utf8
- collation-server=utf8_general_ci
- # 默认使用"mysql_native_password"插件认证
- default_authentication_plugin=mysql_native_password
- # 创建新表时将使用的默认存储引擎
- default-storage-engine=INNODB
在mysql5.7升级的时候,MySQL启动后还需执行
mysql_upgrade
后重启MySQL。MySQL8.0.16
开始,MySQL 不推荐使用mysql_upgrade
;直接使用mysqld_safe
直接启动。关于--upgrade=
的一些参数
--upgrade=AUTO
MySQL升级所有过时的内容
--upgrade=NONE
MySQL跳过升级步骤,可能会导致报错
--upgrade=MINIMAL
MySQL在必要时升级数据字典表,information_schema
和information_schema
。这可能会导致部分功能不能正常使用,例如MGR
--upgrade=FORCE
MySQL会升级所有的内容,这会检查所有schema的所有对象,导致MySQL需要更长的时间启动。此模式下MySQL会重新创建系统表if they are missing
。
- [root@srebro.cn ~]# /home/application/mysql/mysql8/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql --upgrade=FORCE
-
- 2023-10-30T07:33:23.595626Z mysqld_safe Logging to '/home/application/mysql/mysql-error.log'.
- 2023-10-30T07:33:23.620303Z mysqld_safe Starting mysqld daemon with databases from /home/application/mysql/data
-
-
- 会一直卡住不用担心
新开一个窗口,可观察下错误日志看是否报错
/home/application/mysql/mysql-error.log
然后登录数据库测试
- [root@srebro.cn ~]# mysql -uroot -p'srebro'
- Enter password:
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 12
- Server version: 8.0.34 MySQL Community Server - GPL
-
- Copyright (c) 2000, 2022, Oracle and/or its affiliates.
-
- Oracle is a registered trademark of Oracle Corporation and/or its
- affiliates. Other names may be trademarks of their respective
- owners.
-
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
-
-
-
-
- mysql> select version();
- +-----------+
- | version() |
- +-----------+
- | 8.0.34 |
- +-----------+
- 1 row in set (0.00 sec)
-
- mysql>
-
由于basedir 从
/home/application/mysql/app
变成了/home/application/mysql/mysql8
,需要修改下环境变量信息:
- [root@srebro.cn ~]# vim /etc/profile
- export PATH=$PATH:/home/application/mysql/mysql8/bin
- .......
-
-
- #使环境变量生效
- [root@srebro.cn ~]# source /etc/profile
-
- #验证下mysql环境变量
- #退出当前终端
- [root@srebro.cn ~]# exit
-
- [root@srebro.cn ~]# which mysql
- /home/application/mysql/mysql8/bin/mysql
-
- [root@srebro.cn ~]# mysql -V
- mysql Ver 8.0.34 for Linux on x86_64 (MySQL Community Server - GPL)
-
- [root@cmdb ~]# kill -9 `ps -ef | grep mysql | awk '{print $2}'`
-
-
- #确认没有mysql进程
- [root@cmdb ~]# ps -ef | grep mysql
-
-
- #使用systemd管理mysql8
- #修改原先的ExecStart中,basedir的路径,改为mysql8 的路径
-
- [root@cmdb ~]# vim /etc/systemd/system/mysqld.service
-
- [Unit]
- Description=MySQL Server
- Documentation=man:mysqld
- Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
- After=network.target
- After=syslog.target
-
- [Install]
- WantedBy=multi-user.target
- [Service]
- User=mysql
- Group=mysql
- ExecStart=/home/application/mysql/mysql8/bin/mysqld --defaults-file=/etc/my.cnf
- #reload下systemd
- [root@cmdb ~]# systemctl daemon-reload
-
-
- #加入开机自启动
- [root@cmdb ~]# systemctl enable mysqld
- Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld.service to /etc/systemd/system/mysqld.service.
-
- #启动mysql8数据库
- [root@cmdb ~]# systemctl start mysqld
-
-
- [root@cmdb ~]# ps -ef | grep mysql
- mysql 9497 1 36 14:59 ? 00:00:01 /home/application/mysql/mysql8/bin/mysqld --defaults-file=/etc/my.cnf
- root 9544 8560 0 14:59 pts/0 00:00:00 grep --color=auto mysql
-
-
- #登录数据库验证
- [root@cmdb ~]# mysql -uroot -p'srebro'
- Enter password:
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 8
- Server version: 8.0.34 MySQL Community Server - GPL
-
- Copyright (c) 2000, 2023, Oracle and/or its affiliates.
-
- Oracle is a registered trademark of Oracle Corporation and/or its
- affiliates. Other names may be trademarks of their respective
- owners.
-
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
-
- mysql> select version();
- +-----------+
- | version() |
- +-----------+
- | 8.0.34 |
- +-----------+
- 1 row in set (0.00 sec)
-
- mysql> show databases;
- +--------------------+
- | Database |
- +--------------------+
- | information_schema |
- | mysql |
- | performance_schema |
- | srebro |
- | sys |
- | test |
- +--------------------+
- 5 rows in set (0.00 sec)
-
- mysql>
-
在升级Mysql8.0
后,关于JDBC中SSL连接的一些报错信息,如下图:
image-20231030161129369
image-20231030161421640
经排查发现,Mysql8.0
数据库默认开启了SSL
认证,且之前Mysql5.7.39
也是默认开启了SSL
认证,代码和JDBC
驱动版本都没有变化,那很有可能就是Mysql8.0
中对于SSL
的一个变化,咨询了DBA 朋友,专业的解释是,在5.7.31
的时候SSL在源码中貌似没有真正的起作用,后面版本完善了这块的内容。倘若,不使用SSL
去连接,就 需要按照如下的方法去处理:
方法一:从数据库成面,直接在my.cnf 中 添加skip_ssl
参数,从源头上关闭SSL 认证的方式
方法二:从代码层面,在JDBC
连接中,使用 &useSSL=false
参数,表示不使用SSL 认证
Mysql 报错unblock with ‘mysqladmin flush-hosts’,报错如下:
JDBC连接报错,报错内容 ERROR 1129 (HY000): Host '192.168.1.34' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
原因
:同一个ip在短时间内产生太多,中断的数据库连接而导致的阻塞;而中断的因为有些业务使用SSL
去连接数据库,导致登录失败,登录被锁;
临时解决方法,使用mysqladmin flush-hosts
命令清理一下hosts文件,mysqladmin -u xxx -p flush-hosts
,根本上去解决,就需要排查什么异常的连接导致阻塞,登录被锁,比如上面提到的SSL
认证的问题。
https://www.modb.pro/db/1715541568826990592
https://www.modb.pro/db/530848
https://www.modb.pro/db/1716302208709517312
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。