1 前言
关键补丁更新是针对多个安全漏洞的补丁的集合。用以解决Oracle代码和Oracle产品中包含的第三方组件的漏洞。Oracle会定期发布相关补丁,MySQL被包含在其中。用户可以通过订阅邮件、浏览Oracle网站来获取相关信息。
获取关键补丁信息的同时会涉及到关键词汇Common Vulnerabilities and Exposure (CVE) ,CVE是一个行业标准,使用它可以简化识别外部报告的漏洞。https://cve.mitre.org/
Oracle在官网“https://www.oracle.com/security-alerts/” 提供了安全信息,用户可以通过该网页获得安全漏洞,以及关键补丁的内容。对于MySQL的用户而言,查看方式如下:
用户打开链接会看到一个列表,该列表显示了近5年发布的关键补丁(5年是大多数Oracle产品的标准支持范围)。
以2022年10月发布的关键补丁为例,当用户点击链接后,可以看到受影响的Oracle产品列表,包括产品名称和版本,这里以MySQL为例。
下一步,用户选择相关的产品,这里以MySQL服务器软件为例。
图中显示了CVE号码,对应的产品、产品对应的组件、风险矩阵信息(详细的定义内容请参考“https://www.oracle.com/security-alerts/advisorymatrixglossary.html”),以及最关键的受影响版本信息。以图中的CVE-2022-21635为例,受影响的版本为8.0.29(含)之前版本。因此,用户如需解决对应的安全问题,需要将MySQL升8.0.30之后的版本。
总结一下,用户可以通过及时查看CVE信息,确定受影响的MySQL版本,及时进行升级操作,确保MySQL数据库安全。
Mysql的三种升级方式
搭建高版本从库
搭建一个全新的高版本从库。需要准备新的硬件 或则 原用选项的从库
就地升级(In-place Upgrade)
关闭旧版本mysql,用新的替换旧的二进制文件或软件包,在现有数据目录上重启数据库,执行mysql_upgrade
逻辑升级(Logical Upgrade)
使用备份或导出实用程序(如mysqldump,Xtrabackup)从旧mysql实例导出SQL ,安装新的mysql数据库版本,再将SQL应用于新的mysql实例。
2 准备阶段
2.1升级说明
官方支持的升级路径
同一个大版本中的小版本升级,比如5.7.25到5.7.28。
跨版本升级,但只支持跨一个版本升级,比如5.5到5.6,5.6到5.7。
不支持跨版本的直接升级,比如直接从5.5到5.7,可以先从5.5升级到5.6,再从5.6升级到5.7。
查看当前版本:
[root@localhost ~]# mysql -V
mysql Ver 14.14 Distrib 5.7.25, for Linux (x86_64) using EditLine wrapper
2.1.1 下载MySQL 5.7.28 rpm包
官方下载地址:https://dev.mysql.com/downloads/mysql/
2.1.2 备份
备份很重要,防止升级失败(实际操作时以实际环境目录结构为准)
备份数据文件
[root@localhost ~]# cat /etc/my.cnf |grep datadir
#datadir=/var/lib/mysql
datadir=/file/mysql
[root@localhost ~]# cp -pr /file/mysql/ /file/mysql.bak
备份配置文件
[root@localhost ~]# cp /etc/my.cnf /etc/my.cnf.bak
备份sql数据
[root@localhost ~]# mysqldump -uroot -p --opt --socket=/file/mysql/mysql.sock --all-databases > /root/backup/mysqlbackup.20191226.sql
3 搭建高版本从库方式升级
3.1从库搭建
解压Percona Server 5.7.30的安装包并部署。
通过备份工具可把主库的数据进行在线热备
###############mysqldump方式
#1.备份
mysqldump -ubakuser -p123456 -h127.0.0.1 -P3310 --opt --hex-blob --single_transaction -R --default-character-set=utf8 --master-data=2 --all-databases>/temp/dbfull.sql
#2. 在新从库服务器恢复
mysql>source /temp/dbfull.sql;
###############xtrabakcup方式
#1.备份
innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password=******* /opt/idbbak/
#2.在新从库服务器恢复
//--apply-log选项的命令是准备在一个备份上启动mysql服务
# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log /opt/idbbak/2020-06-16-16-35-12
//--copy-back 选项的命令从备份目录拷贝数据,索引,日志到my.cnf文件里规定的初始位置
# innobackupex --defaults-file=/etc/my.cnf --user=root --copy-back /opt/idbbak/2020-06-16-16-35-12
//文件目录授权之后 启动数据库
#chown -R mysql.mysql /opt/data
#mysqld_safe –user=mysql&
配置主从关系:
#1.确认备份主库的 gtid位置
##mysqldump方式
#less /temp/dbfull.sql
备份当时gtid 已执行:
SET @@GLOBAL.GTID_PURGED='9f39465a-7e30-11e9-8f85-fa163e5def9a:1-4';
##xtrabackup方式
cat /opt/idbbak/2020-06-16-16-35-12/xtrabackup_info
GTID of the last change '9f39465a-7e30-11e9-8f85-fa163e5def9a:1-4'
#配置主从关系,登录从数据库
mysql>stop slave;
mysql>reset master;
mysql>SET @@GLOBAL.GTID_PURGED= '9f39465a-7e30-11e9-8f85-fa163e5def9a:1-4'
mysql>change master to
master_host = '10.1.1.12',
master_port = 3310,
master_user = 'repl',
master_password = '********',
master_auto_position=1;
mysql>start slave;
mysql>show slave status\;
命令查看下列参数值为
Slave_IO_Running:YES
Slave_SQL_Running:YES
注意主从配置参数:
#每个server服务的标识,在master/slave环境中,此变量一定要不一样
server-id=1
每个server服务的标识,在master/slave环境中,此变量一定要不一样
#制以什么格式记录二进制日志的内容
binlog_format=row
#设定所接受的包的大小
max_allowed_packet=1G
#队列中Pending的事件所占用的最大内存,默认为16M
#需要大于主库max_allowed_packet的大小
slave_pending_jobs_size_max=2G
4 就地升级(In-place Upgrade)方式升级
4.1配置MySQL以通过设置innodb_fast_shutdown为执行慢速关闭 0
[root@localhost ~]# mysql -u root -p --execute="SET GLOBAL innodb_fast_shutdown=0" //在关闭过程中,InnoDB执行完全清除并在关闭之前更改缓冲区合并,这可确保在发布版本之间存在文件格式差异时完全准备好数据文件
4.2 关闭当前mysql服务
[root@localhost ~]# ps -ef |grep mysql |grep -v color
mysql 1061 1 0 09:24 ? 00:00:09 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
[root@localhost ~]# mysqladmin -u root -p --socket=/file/mysql/mysql.sock shutdown
[root@localhost ~]# ps -ef |grep mysql |grep -v color
4.3 卸载mysql5.7.25并解压安装mysql.5.7.28
[root@localhost mysql_rpm]# rpm -qa |grep mysql
mysql-community-client-5.7.25-1.el7.x86_64
mysql-community-libs-5.7.25-1.el7.x86_64
mysql-community-common-5.7.25-1.el7.x86_64
mysql-community-server-5.7.25-1.el7.x86_64
[root@localhost mysql_rpm]# rpm -qa |grep mysql |xargs rpm -ev --nodeps
[root@localhost mysql_rpm]# rpm -qa |grep mysql
[root@localhost mysql_rpm]# rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
[root@localhost mysql_rpm]# rpm -ivh mysql-community-libs-5.7.28-1.el6.x86_64.rpm
[root@localhost mysql_rpm]# rpm -ivh mysql-community-client-5.7.28-1.el6.x86_64.rpm
[root@localhost mysql_rpm]# rpm -ivh libaio-0.3.107-10.el6.x86_64.rpm
[root@localhost mysql_rpm]# rpm -ivh mysql-community-server-5.7.28-1.el6.x86_64.rpm --nodeps
[root@localhost mysql_rpm]# rpm -qa |grep mysql
mysql-community-libs-5.7.28-1.el6.x86_64
mysql-community-common-5.7.28-1.el7.x86_64
mysql-community-client-5.7.28-1.el6.x86_64
mysql-community-server-5.7.28-1.el6.x86_64
4.4 依赖包检查
注意:rpm包有严格的依赖关系,必须按照顺序执行安装:
mysql-community-common-5.7.24-1.el6.x86_64.rpm
mysql-community-libs-5.7.24-1.el6.x86_64.rp
mysql-community-client-5.7.24-1.el6.x86_64.rpm
libaio-0.3.107-10.el6.x86_64.rpm(若在有网情况下可执行yum install libaio)
mysql-community-server-5.7.24-1.el6.x86_64.rpm
安装mysql-community-server前需要安装libaio
下载地址http://mirror.centos.org/centos/6/os/x86_64/Packages/libaio-0.3.107-10.el6.x86_64.rpm
4.5 初始化数据库
[root@localhost ~]# cp /etc/my.cnf.bak /etc/my.cnf
[root@localhost ~]# mysqld --initialize --user=mysql --explicit_defaults_for_timestamp //执行完成后查看 /var/log/mysqld.log日志中可看到root用户的初始密码
4.6 启动服务
[root@localhost ~]# mysql -uroot –p //输入自动生成的初始密码
//或者在配置文件添加skip-grant-tables,重启服务跳过密码验证,配置新密码后再删除这条配置
(root@localhost) [mysql] 11:33:53> set password = password("yournewpassword");
Query OK, 0 rows affected, 1 warning (0.00 sec)
(root@localhost) [mysql] 11:34:22> ALTER USER 'root'@'localhost' PASSWORD EXPIRE NEVER;
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [mysql] 11:34:33> flush privileges;
Query OK, 0 rows affected (0.00 sec)
[root@localhost ~]# mysql -uroot –p //登陆验证密码是否生效
4.7 Mysql数据结构升级
[root@localhost ~]# mysql_upgrade -uroot -p --socket=/file/mysql/mysql.sock
Enter password:
Checking if update is needed.
Checking server version.
Running queries to upgrade MySQL server.
Checking system database.
mysql.columns_priv OK
mysql.db OK
mysql.engine_cost OK
mysql.event OK
mysql.func OK
mysql.general_log 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.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.proxies_priv 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
The sys schema is already up to date (version 1.5.2).
Checking databases.
sys.sys_config OK
Upgrade process completed successfully.
Checking if update is needed.
4.8 再次查看版本,到此升级成功
[root@localhost ~]# mysql –V
mysql Ver 14.14 Distrib 5.7.28, for Linux (x86_64) using EditLine wrapper
(root@localhost) [(none)] 11:55:45> select@@version; //登陆数据库也可查看版本
+-----------+
| @@version |
+-----------+
| 5.7.28 |
+-----------+
1 row in set (0.00 sec)
5 逻辑升级(Logical Upgrade)方式升级
多用于跨度大的版本升级,一般是用于一台服务器迁移到另一台服务器。
例如,从5.1.73升级到5.7.26
首先利用MySQLDUMP 出数据库文件,由于版本差距太大,把导出的SQL文件引擎全部换成INNODB。
在5.1.73库上执行:
mysql -S /tmp/mysql.sock -uroot -p smsdbtest > /soft/smsdbtest.sql
把导出的文件传到安装的5.7.26库上进行导入:
导入:
mysql -S /tmp/mysql3307.sock -uroot -p smsdbtest < /soft/smsdbtest.sql
导入成功,并进行检查。
6 回退之前版本
6.1 调整配置文件
[root@localhost ~]# cat /etc/my.cnf
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql5725_bak/data/ # 备份的数据
server_id=3356
port=3356 # 新起一个端口,生产用原来端口即可
socket=/tmp/mysql.sock
[root@localhost ~]#
6.2 修改备份数据属主
[root@localhost data]# chown -R mysql:mysql mysql5725_bak
6.3 启动服务
[root@localhost ~]# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &
[1] 20111
[root@localhost ~]# 220103 23:26:07 mysqld_safe Logging to '/data/3306_bak/data/localhost.localdomain.err'.
220103 23:26:07 mysqld_safe Starting mysqld daemon with databases from /data/3306_bak/data
6.4 检查
[root@localhost ~]# netstat -lntup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 14827/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 6526/master
tcp6 0 0 :::22 :::* LISTEN 14827/sshd
tcp6 0 0 ::1:25 :::* LISTEN 6526/master
tcp6 0 0 :::3356 :::* LISTEN 20250/mysqld
[root@localhost ~]# # 3356 端口已监听
验证
[root@localhost ~]# mysql -uroot -S /tmp/mysql.sock
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
[root@localhost ~]# mysql -uroot -p -S /tmp/mysql.sock
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.25 MySQL Community Server (GPL) # 此时已回退到升级前的版本
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
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> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sysbenchdb |
| test |
+--------------------+
5 rows in set (0.02 sec)
mysql> use sysbenchdb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from sbtest1 limit 1;
+----+------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k | c | pad |
+----+------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| 1 | 3231 | 68487932199-96439406143-93774651418-41631865787-96406072701-20604855487-25459966574-28203206787-41238978918-19503783441 | 22195207048-70116052123-74140395089-76317954521-98694025897 |
+----+------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>