暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

绿盟?MySQL漏洞?你需要的实用帖来了!!!

恒生DBA公社 2021-04-21
4219


 前言 

因证监会审计的要求,目前很多客户都被第三方安全软件(如绿盟)扫描出了一些安全漏洞,包括主机,数据库,中间件的漏洞。


一般扫描软件都有自己的漏洞库,会根据漏洞库的规则去扫描,如果符合规则的,就输出视为漏洞,这个漏洞库,都是基于每个版本已经发布或者已经发现的漏洞,很多新版本的补丁都会修复这些漏洞,所以扫描到的漏洞基本上就建议升级。





 案例场景 

最近有个XX证券客户被绿盟审计扫了一下系统,有一些补丁漏洞的,其中有几台是mysql系统,版本有5.5,5.6,5.7三个不同的版本。对于这类漏洞问题,基本方法就是打上对应的补丁,大致的情况如下



针对此类漏洞,一般我们的方法就是打上最新比较稳定的补丁,例如官网有下面一段话:

The following tablelists the minimum revisions of MySQL Server 5.5.x, 5.6.x, 5.7.x required toresolve each of the vulnerabilities included in the April 2017 CriticalPatch Update.

However, we recommendupgrading to the latest release for each version to get the latest patches. Forinformation on how to download the latest MySQL Server releases,

containing the latestsecurity fixes, see [3] below.



因此建议分别升级到5.5.56,5.6.36,5.7.18三个版本。







 升级方案 

对于mysql支持的升级方法有两种In-place Upgrade 和 Logical Upgrade, 暂时翻译为替换升级和逻辑升级。


替换升级:

停止mysql服务,替换原来的旧版本的mysql软件,用新的mysql软件启动mysql, 最后用mysql_upgrade更新数据库字典表等。

 

逻辑升级:

用mysqldump导出备份,安装新版本的mysql,导入mysqldump 备份。

Mysqldump相当于oracle里面的exp/expdp等工具,导出的备份为sql语句,因此可靠性最好,但是在速度上就比较慢了。


Mysql_upgrade检查数据库中所有表是否与当前的mysql软件系统库版本相兼容,同时它会更新系统表以便系统能用到新版本的权限与特性。


对于升级的路径,即可以在一个大版本内的如5.7.95.7.10,也可以是大版本之前的升级如5.65.7。

有一点要注意的是不要在大版本之间跳跃性的升级如5.5直接到5.7, 应该先升级5.6 再升级到5.7.








 升级前准备 

升级前的准备非常重要,将对升级起着至关重要作用。在升级之前应该做好一些如下准备工作:

 1. 做好备份

备份好之前的软件目录、数据文件目录、参数文件和相关日志文件。

 2. 研究好新版本

研究好目标版本的一些新变化,有哪些新特性,这些新特性是否需要在数据为层面和应用层面做出一些改变,哪些新变量、参数和功能在新版本中已经被移除了。例如你想更新到mysql5.7 就需要好好研究下Release Notes关于新特性, Section1.5, “Server and Status Variables and Options Added, Deprecated, or Removed in MySQL 5.7”. 关于移除的新特性。如innodb_additional_mem_pool_size这个参数从5.6.3开始已经被抛弃了,之前这个参数相当于oracle里面的pga,起着非常重要的作用

 3. 表和索引是否需要被重建

 4. 如果涉及到其它的如复制,需要有特殊的步骤等。



 In-place Upgrade 

1. 做一个完整的关闭 (innodb_fast_shutdown=0)

命令可以参考如下

mysql -u root -p --execute="SET GLOBALinnodb_fast_shutdown=0"

0表示在innodb关闭的时候,需要purge all, merge insert buffer,flush dirty pages。这是最慢的一种关闭方式,但是restart的时候也是最快的

2. 关闭mysql

mysqladmin -u root -p shutdown

3. 备份相关文件

老的mysql软件安装目录、数据文件目录、日志目录、参数文件

4. 解压新版本的mysql软件并替换原来mysql软件安装目录

5. 对于新版本mysql软件按需要更新参数文件

6. 用新的mysql软件去启动mysql数据库

mysqld_safe --user=mysql--datadir=/path/to/existing-datadir

7. 运行mysql_upgrade

mysql_upgrade -u root -p

8. 关闭并重新启动mysql

mysqladmin -u root -p shutdown

mysqld_safe--user=mysql --datadir=/path/to/existing-datadir






 Logical Upgrade 

1. 用mysqldump做一个完整的mysql逻辑备份

mysqldump -u root -p

--add-drop-table --routines --events

--all-databases --force >data-for-upgrade.sql

2. 关闭mysql

3. 安装新版本mysql

4. 启动新版本mysql

5. 导入新版本的mysqldump备份文件

mysql -u root -p --force <data-for-upgrade.sql

6.  mysql_upgrade

mysql_upgrade -u root -p

7. 重启下mysql

mysqladmin -u root -p shutdown

mysqld_safe --user=mysql--datadir=/path/to/5.7-datadir





 注意事项 

1. 仅供参考

有些命令在实际过程中是有些区别的,例如,重起mysql服务你可能用service mysql start 这样的操作。

2. 在升级过程中有可能造成mysql的表和索引失效,需要重新rebuild. 

例如此是你可以用CHECK TABLE ... FOR UPGRADE语句去找出需要重建的表和索引,如果有需要重建的表,日志中便有以下语句:

Table upgrade required.

Please do "REPAIR TABLE `tbl_name`"or dump/reload to fix it!

我们可以用Repair Table tbl_name去重建表或者利用备份文件dump/reload去重新导入表。

还有一种方法就是用mysqlcheck --check-upgrade 或者 mysql_upgrade,最终也会调用checktable


重建表有下面相关命令:

重建单个表:

mysqldump db_name t1 > dump.sql

mysql db_name < dump.sql

 

重建一个库中多个表:

mysqldump db_name > dump.sql

mysql db_name < dump.sql

 

重建所有库中所有表:

mysqldump --all-databases > dump.sql

mysql < dump.sql


rebuild一个表:

ALTER TABLE t1 ENGINE = InnoDB;

REPAIR TABLE t1;

mysqlcheck --repair --databases db_name ...

mysqlcheck --repair --all-databases






 复制环境的升级 

上面这么多讲的都是针对单机mysql,但是实际的生产环境一般都不是单机,一般有主从复制、mha,mgr等。但是根本都是复制或者复制的加强变体,所以这里我们就讲一讲复制环境的升级。


1. 当我们要升级复制环境时,升级步骤和mysql复制环境的版本有很大关系,不同的源版本和目标版本有不同操作。但是有一个大概的思路就是先升级slave, 再升级master, 比如你想要升级到5.7.x时,你升级master之前要确保所有的slave都是mysql5.7.x版本。我们先升级好后每个slave后,重启slave,重启复制,以mysql5.7新版本的slave logs 启动replication,然后再去升级master。


2. 除版本自身因素外,SQL MODE也是个非常重要的因素。因为SQL mode可能会导致升级后复制失效,例如mysql5.7.2版本,服务器在对sql modeSTRICT_TRANS_TABLES or STRICT_ALL_TABLES下的临时数据类型的默认值0的插入有非常严格的要求,如果参数binlog_format=STATEMENT,此时如果只升级了slave,master会报错导致复制失效,处理这种情况,我们应停止master上的业务,让slave同步赶上master,当slavemaster一致后,我们再接着升级。相反,如果主库上的业务不能停,那么就临时把binlog_format改成row_based,至到所有的slavemaster同步一致后,才开始升级slave. 因此我们再做复制环境的升级时一定要先检查从库是否跟上主库。


3. 最后在升级完成后,某些情况我们可能需要单独重建某个对象,例如重建表,重建索引,这时我们需要单独安全的在某个结点执行操作。

此时我们还需要注意下几点:

3.1 停止所有slave进行升级,升级完成后用--skip-slave-start去重启slave, slave就不会去连master,此时可以做一些rebuilding

操作如repaire table 或者alter table 或者dump and reload table.


3.2  master上用sql_log_bin=0参数去重启主库,禁止产生binlog,同时用--skip-networking选项禁止tcp/ip连接,然后再进行类似rebuild操作,然后再用sql_log_bin=1,同时不带--skip-networking参数去开启主库,以便于slave能连接上master.


3.3 重启slave,不带--skip-slave-start,这样slave就会去连主库






 总结 

好了,这里总结了mysql相关升级的一些概念与操作步骤,从升级前、升级步骤和升级后三个非常粗粒度的角度去描述了一些基本概念与注意事项,升级前准备好、做好备份,升级过程仔细小心,升级后检查检查再检查,完了做好应用测试,升级就不是问题。

参考:

Critical Patch Update April 2013 PatchAvailability Document for Oracle MySQL Products (Doc ID 1536938.1)

MySQL 5.7 Reference Manual



文章转载自恒生DBA公社,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论