MySQL降级原理与实战演练

MySQL降级原理与实战演练

第一章 MySQL降级原理与分类

MySQL降级原理

  • MySQL降级的原理与升级类似,即使用低版本软件挂载高版本的数据目录并启动,完成系统表降级。降级比升级更不常见。降级通常是由于生产系统上发生兼容性或性能问题而执行,并且在测试系统的初始升级验证期间没有发现。与升级过程一样,在生产系统上使用降级过程之前,请先在某些测试系统上执行并验证它。

MySQL降级途径

  • 只有在一般可用性(GA)版本之间才支持降级。
  • 使用逻辑降级方法支持从MySQL 5.7降级到5.6。
  • 不支持跳过版本的降级。例如,直接从MySQL 5.7降级到5.5。
  • 支持在发布系列中降级。例如,支持从MySQL 5.7.z降级到5.7.y。还支持跳过发布。例如,支持将MySQL 5.7.z降级为5.7.x。

MySQL降级分类

  • Inplace Downgreding
    In-place降级涉及关闭新的MySQL版本,用旧的MySQL二进制文件或包替换原来高版本的MySQL版本,并在现有的数据目录上重新启动旧的MySQL版本。对于同一发布系列内的GA发布之间的降级,支持就地降级。MySQL APT、SLES和Yum存储库安装不支持就地降级。

  • Logical Downgrading
    逻辑降级包括使用MySQL dump转储新MySQL版本中的所有表,然后将转储文件加载到旧MySQL版本中。对于同一版本系列内的不同版本之间的降级以及降级到以前的版本级别,都支持逻辑降级。仅支持在同一发布系列内(GA)版本之间降级。

第二章 MySQL降级注意事项

MySQL降级注意事项

  • 一定要备份原有数据
  • 先在测试环境测试,确认没有问题在投产
  • MySQL5.7版本Inplace Downgrading最低支持降级到MySQL5.7.10
  • 降级一般很少用到
  • Logical Downgrading只支持5.7降级到5.6,不支持5.7降级到5.5,也不支持8.0降级
  • MySQL8.0降级只能使用备份恢复方法,即升级前备份,回退的时候使用备份恢复

第三章 实战环境准备

原有环境

二进制部署参考博客:https://www.pingface.com/2020/04/mysql5728.html
MySQL版本:5.7.28
配置文件路径:/etc/my.cnf
数据目录:/data/3306/data
软件安装目录:/data/app/mysql

第四章 实战演练MySQL之Inplace Downgrading

MySQL5.7.28就地降级到MySQL5.7.10

1.安装部署MySQL5.7.10

$ tar xf mysql-5.7.10-linux-glibc2.5-x86_64.tar.gz
$ mv mysql-5.7.10-linux-glibc2.5-x86_64 mysql-5.7.10
$ ln -s /data/app/mysql-5.7.10 /data/app/mysql5710

$ cat > /data/5710/my.cnf <<EOF 
[mysqld]
user=mysql
basedir=/data/app/mysql5710
datadir=/data/5710/data
socket=/data/socket/mysq5710.sock
port=5710
server_id=57
EOF

$ /data/app/mysql5710/bin/mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql5710 --datadir=/data/5710/data

2.更改MySQL5.7.28系统表配置

MySQL官方降级指导文档

set sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
set global sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
select @@sql_mode;                              
ALTER TABLE mysql.proc MODIFY definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.event MODIFY definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.tables_priv MODIFY Grantor char(77) COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.procs_priv MODIFY Grantor char(77) COLLATE utf8_bin NOT NULL DEFAULT '';

3.优雅关闭MySQL5.7.28

mysql> set global innodb_fast_shutdown=0 ;
$ mysql -uroot -pxxx --execute="SET GLOBAL innodb_fast_shutdown=0"
$ mysqladmin -uroot -pxxx shutdown

4.删除ib_logfile日志文件

$ rm -rf /data/3306/data/ib_logfile*

5.修改配置

# 替换成低版本路径指向
$ vim /etc/my.cnf
[mysqld]
user=mysql
basedir=/data/app/mysql5710
datadir=/data/3306/data
socket=/data/socket/mysql5710.sock
port=5710
[mysql]
socket=/data/socket/mysql5710.sock

6.修改环境变量

$ vim /etc/profile
  export PATH=/data/app/mysql5710/bin:$PATH
$ source /etc/profile
$ mysql -V
  mysql  Ver 14.14 Distrib 5.7.10, for linux-glibc2.5 (x86_64) using  EditLine wrapper

7.启动数据库

$ /etc/init.d/mysqld start
$ netstat -lntup|grep mysql
  tcp6       0      0 :::5710     :::*     LISTEN      3309/mysqld

8.执行mysql_upgrade并验证降级

$ mysql_upgrade -uroot -pxxx -S /data/socket/mysql5710.sock --forc
# 屏幕输出一列OK,最后两行有Upgrade process completed successfully表示降级更新系统表成功!
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.10    |
+-----------+

第五章 实战演练MySQL之Logical Downgrading

MySQL5.7.28逻辑降级到MySQL5.6.46

1.二进制部署MySQL5.6.46

参考:https://www.pingface.com/2020/04/mysqlmulti.html

2.更改MySQL5.7.28系统表配置

MySQL官方降级指导文档

set sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
set global sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
select @@sql_mode;   
ALTER TABLE mysql.proc MODIFY definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.event MODIFY definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.tables_priv MODIFY Grantor char(77) COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.procs_priv MODIFY Grantor char(77) COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.tables_priv MODIFY User char(16) NOT NULL default '';
ALTER TABLE mysql.columns_priv MODIFY User char(16) NOT NULL default '';
ALTER TABLE mysql.user MODIFY User char(16) NOT NULL default '';
ALTER TABLE mysql.db MODIFY User char(16) NOT NULL default '';
ALTER TABLE mysql.procs_priv MODIFY User char(16) binary DEFAULT '' NOT NULL;
ALTER TABLE mysql.user ADD Password char(41) character set latin1
collate latin1_bin NOT NULL default '' AFTER user;
UPDATE mysql.user SET password = authentication_string WHERE
LENGTH(authentication_string) = 41 AND plugin = 'mysql_native_password';
UPDATE mysql.user SET authentication_string = '' WHERE
LENGTH(authentication_string) = 41 AND plugin = 'mysql_native_password';
ALTER TABLE mysql.help_category ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.help_keyword ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.help_relation ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.help_topic ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone_leap_second ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone_name ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone_transition  ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone_transition_type ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.plugin ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.servers ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.user MODIFY plugin CHAR(64) COLLATE utf8_bin
DEFAULT 'mysql_native_password';
DROP DATABASE sys;

3.逻辑备份5.7.28数据

$ mysqldump -A >/tmp/full.sql
$ /etc/init.d/mysqld stop

4..修改配置

# 在参考博客中,已经部署好mysql5.6.46,并设置了systemd启动,这里就不需要默认配置了,只要把备份的数据在5.6.46恢复即可。
$ mv /etc/my.cnf /etc/my.cnf.bak

$ cat /etc/systemd/system/mysqld3316.service 
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
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=/data/app/mysql5646/bin/mysqld --defaults-file=/data/3316/my.cnf
LimitNOFILE = 5000
$ cat /data/3316/my.cnf
[mysqld]                    
user=mysql                  
basedir=/data/app/mysql5646    
datadir=/data/3316/data     
socket=/data/socket/mysql3316.sock       
port=3316                   
server_id=16

5.修改环境变量

$ vim /etc/profile
  export PATH=/data/app/mysql5646/bin:$PATH
$ source /etc/profile
$ mysql -V
  mysql  Ver 14.14 Distrib 5.6.46, for linux-glibc2.12 (x86_64) using  EditLine wrapper

6.恢复备份数据到5.6.46中

$ systemctl start mysqld3316
$ netstat -lntup|grep mysql
  tcp6       0      0 :::3316     :::*      LISTEN    1839/mysqld

$ mysql -S /data/socket/mysql3316.sock
mysql> source /tmp/full.sql
......
Query OK, 0 rows affected (0.00 sec)

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.6.46    |
+-----------+