一、为什么升级MySQL

  • 基于安全考虑
  • 基于性能和稳定性考虑:mgr复制 ,并行复制writeset 等功能,性能提升
  • 新的功能:Hash join ,窗口函数,DDL即时,json 支持
  • 原始环境中版本太多,统一版本
  • 8.0版本基本已到稳定期,可以大量投入生产环境中

二、升级前注意事项

  • 注意字符集设置。为了避免新旧对象字符集不一致的情况,可以在配置文件将字符集和校验规则设置为旧版本的字符集和比较规则。
  • 密码认证插件变更。为了避免连接问题,可以仍采用5.7的mysql_native_password认证插件。
  • sql_mode支持问题。8.0版本sql_mode不支持NO_AUTO_CREATE_USER,要避免配置的sql_mode中带有NO_AUTO_CREATE_USER。
  • 是否需要手动升级系统表。在MySQL 8.0.16版本之前,需要手动的执行mysql_upgrade来完成该步骤的升级,在MySQL 8.0.16版本及之后是由mysqld来完成该步骤的升级。
  • 高可用架构下 需要先升级从库,再逐步升级主库。

三、MySQL升级方法选择

MySQL升级_脚本


跨版本升级:

可行:

5.5.57 --> 5.6.48

5.5.62 --> 5.7.30

5.6.37 --> 5.7.19

5.7.30 --> 8.0.19

不可行,需要使用中间版本过度:
5.5.62 --> 8.0.19
5.6.37 --> 8.0.19

否则会报错:
2020-06-12T09:16:11.308870Z 1 [System] [MY-011012] [Server] Starting upgrade of data directory.
2020-06-12T09:16:12.859161Z 1 [ERROR] [MY-013168] [InnoDB] Cannot upgrade server earlier than 5.7 to 8.0
2020-06-12T09:16:17.967602Z 1 [ERROR] [MY-011013] [Server] Failed to initialize DD Storage Engine.
2020-06-12T09:16:17.968104Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
 
下面的报错可以解决:
2020-06-12T09:12:22.666062Z 1 [ERROR] [MY-013090] [InnoDB] Unsupported redo log format (0). The redo log was created before MySQL 5.7.9
2020-06-12T09:12:22.666195Z 1 [ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error Generic error.
2020-06-12T09:12:23.166811Z 1 [ERROR] [MY-011013] [Server] Failed to initialize DD Storage Engine.
2020-06-12T09:12:23.167375Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
解决:删除日志文件,rm -rf ib_logfile*
 
报错:
2020-06-12 17:28:27 7191 [ERROR] Plugin 'InnoDB' init function returned error.
2020-06-12 17:28:27 7191 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2020-06-12 17:28:27 7191 [ERROR] Unknown/unsupported storage engine: InnoDB
解决:删除日志文件,rm -rf ib_logfile*

四、MySQL升级

注意:一定要进行备份。

在关闭mysql时,参数innodb_fast_shutdown影响着表的存储引擎为innodb的行为,参数为0、1、2三个值。

  • 0代表当MYSQL关闭时,Innodb需要完成所有full purge和merge insert buffer操作,这需要花费时间来完成。如果做Innodb plugin升级,通常需要将这个参数调为0,然后再关闭数据库
  • 1是参数的默认值,不需要完成full purge和merge insert buffer操作,但是在缓冲池的一些数据脏页还是会刷新到磁盘。
  • 2表示不需要完成full purge和merge insert buffer操作,也不将缓冲池中的数据脏页写回磁盘,而是将日志都写入日志文件。这样不会有任何事务丢失,但是mysql在下次启动时,会执行恢复操作(recovery)

5.5.62升级到5.7.30

1、解压mysql5.7软件

tar -zxvf mysql-5.7.30-linux-glibc2.12-x86_64.tar.gz
mv  mysql-5.7.30-linux-glibc2.12-x86_64 /usr/local/mysql57

2、 set global innodb_fast_shutdown=0;

3、 关闭MySQL

service mysqld stop

4、 修改my.cnf参数文件,例如basedir参数

[mysqld]
basedir=/usr/local/mysql57
datadir=/usr/local/mysql/data
port=3306
server_id=57303306
log-bin
skip-name-resolve
character_set_server=utf8mb4

5、 使用新版本mysqld_safe启动MySQL,观察错误日志

mysql> mysqld_safe &

6、 若新版本小于8.0.16,那么需要使用 mysql_upgrade -uroot -p123456,观察错误日

[root@lhrc76mysql bin]# ./mysql_upgrade -uroot -plhr -S /tmp/mysql.sock
mysql_upgrade: [Warning] Using a password on the command line interface can be insecure.
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.host                                         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
Upgrading the sys schema.
Checking databases.
sys.sys_config                                     OK
Upgrade process completed successfully.
Checking if update is needed.

7、 用新版本软件正常启动MySQL。

/usr/local/mysql57/bin/mysqladmin -u root -p -S /tmp/mysql.sock shutdown
/usr/local/mysql57/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &

8、 修改环境变量

vi /root/.bashrc

5.7.30升级到8.0.22

1、解压mysql8.0软件

tar -Jxf mysql-8.0.19-linux-glibc2.12-x86_64.tar.xz 
mv mysql-8.0.19-linux-glibc2.12-x86_64 /usr/local/mysql80

2、 set global innodb_fast_shutdown=0;

3、 关闭MySQL

mysqladmin -u root -p -S /tmp/mysql.sock shutdown

4、 修改my.cnf参数文件,例如basedir参数

[mysqld]
basedir=/usr/local/mysql80
datadir=/usr/local/mysql/data
port=3306
server_id=57303306
log-bin
skip-name-resolve
character_set_server=utf8mb4

5、 使用新版本mysqld_safe启动MySQL,观察错误日志

/usr/local/mysql80/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &
 
2020-11-13T14:05:39.727659Z 5 [System] [MY-013381] [Server] Server upgrade from '50700' to '80022' started.
2020-11-13T14:05:44.287495Z 5 [System] [MY-013381] [Server] Server upgrade from '50700' to '80022' completed.

6、 用新版本软件正常启动MySQL。

/usr/local/mysql80/bin/mysqladmin -u root -p -S /tmp/mysql.sock shutdown
/usr/local/mysql80/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &

7、 修改环境变量

vi /root/.bashrc



Mysql5.7.x升级 小版本升级(脚本)

--rpm 包升级

升级操作

注意:
1.升级之前需要备份数据目录,备份前确认要备份目录是否有空间,替换BACK_PATH
2.执行脚本之前验证mysql密码是否能正常登陆,并替换密码参数
3.上传软件到/home/mysql,登录服务器切换到root用户下执行
4.关闭旧版本mysql,用新的替换旧的二进制文件或软件包,在现有数据目录上重启数据库,执行mysql_upgrade
5.漏洞扫描解决:对mysql进行小版本升级到Mysql5.7.19升级到5.7.29及以后就行,此次升级到5.7.38,生产环境无法联网,用rpm 包离线安装,选择就地升级。
6.升级成功之后,由于脚本中带有密码,删除脚本,稳定之后,删除备份。

脚本如下:

UP_SOFT_PATH=/soft/upgrade_soft/
UPGRADETIME=`date +%Y%m%d`
DB_PASSWORD=Pwd_2018
VERSION=5.7.38-1.el6.x86_64
BACK_PATH=/
datadir=`cat /etc/my.cnf | grep datadir |awk -F '=' '{print $2}'`
socket=`cat /etc/my.cnf | grep socket | awk 'NR==1'|awk -F '=' '{print $2}'`

####新建安装包存放目录,并将安装包移动到新建的存放目录UP_SOFT_PATH
mkdir -p $UP_SOFT_PATH

if [[ $? = 0 ]]
then
   echo " dir is done .!!!!!!!"
else
   echo "sorry, pls check out!"
   exit 1
fi


#使用http服务器下发安装包Pwd
cd $UP_SOFT_PATH
if [ -f "mysql-5.7.38-1.el6.x86_64.rpm-bundle.tar" ];then
echo "exsits"
else
cd $UP_SOFT_PATH  &&  wget http://172.50.1.244:8888/db_upgrade/mysql-5.7.38-1.el6.x86_64.rpm-bundle.tar
#cd $UP_SOFT_PATH  &&  wget http://172.50.1.244:8888/db_upgrade/mysql-8.0.29-1.el7.x86_64.rpm-bundle.tar
fi

#chown -R root:root $UP_SOFT_PATH
#chmod -R 755 $UP_SOFT_PATH



## auto install mysql_upgrade
## 先停掉服务,并且卸载之前的mysql
mysql -uroot -p${DB_PASSWORD} --execute="SET GLOBAL innodb_fast_shutdown=0" 
#mysql -uroot -pPwd_2017 --execute="SET GLOBAL innodb_fast_shutdown=0" 

if [[ $? = 0 ]]
then
   echo " mysql server parameters is done .!!!!!!!"
else
   echo "sorry, pls check out!"
   exit 1
fi


## 备份配置文件
cp /etc/my.cnf /etc/my.cnf.$UPGRADETIME
#cp /usr/lib/systemd/system/mysqld.service    /usr/lib/systemd/system/mysqld.service.$UPGRADETIME
## 先还原备份配置文件再启动mysql服务
#服务器的操作系统的判断,并关闭数据库
edition=`cat /etc/redhat-release|sed -r 's/.* ([0-9]+)\..*/\1/'`
ed=`cat /etc/redhat-release` 
if [ "X$edition" == "X6"  ]
then
echo -e "INFO `date +%Y-%m-%d_%H:%M:%S` 当前服务器操作系统版本是linux 6版本系统,具体版本:$ed " 
    /etc/init.d/mysqld stop
elif [ "X$edition" == "X7"  ]
then
echo -e "INFO `date +%Y-%m-%d_%H:%M:%S` 当前服务器操作系统版本是linux 7版本系统,具体版本:$ed " 
systemctl stop  mysqld
fi


if [[ $? = 0 ]]
then
   echo " mysql server stop is done .!!!!!!!"
else
   echo "sorry, pls check out!"
   exit 1
fi

echo "备份整个数据目录,冷备和dump有一份即可,此处最耗费时间,备份开始......"
cp -pr $datadir $BACK_PATH/mysql_data.$UPGRADETIME 

if [[ $? = 0 ]]
then
   echo "mysql data backup is done .!!!!!!!"
else
   echo "sorry, pls check out!"
   exit 1
fi

##卸载原数据库
rpm -qa |grep -i mysql |xargs rpm -ev --nodeps

number=`rpm -qa | grep -i mysql|wc -l`
if [ $number -eq 0 ];
then
   echo "uninstall mysql  is done"
else
   echo "sorry, pls check out!"
   exit 1
fi



## 安装新版本数据库
cd $UP_SOFT_PATH
tar -xf mysql-$VERSION.rpm-bundle.tar
rpm -ivh mysql-community-common-$VERSION.rpm --nodeps --force
rpm -ivh mysql-community-libs-$VERSION.rpm --nodeps --force
rpm -ivh mysql-community-client-$VERSION.rpm --nodeps --force
rpm -ivh mysql-community-server-$VERSION.rpm --nodeps --force 


if [[ $? = 0 ]]
then
   echo "install mysql server and client is done .!!!!!!!"
else
   echo "sorry, pls check out!"
   exit 1
fi

## 恢复MySQL参数文件
yes | cp /etc/my.cnf.$UPGRADETIME  /etc/my.cnf     
chown mysql:mysql /etc/my.cnf


## 先还原备份配置文件再启动mysql服务
#服务器的操作系统的判断,并启动数据库
edition=`cat /etc/redhat-release|sed -r 's/.* ([0-9]+)\..*/\1/'`
ed=`cat /etc/redhat-release` 
if [ "X$edition" == "X6"  ]
then
echo -e "INFO `date +%Y-%m-%d_%H:%M:%S` 当前服务器操作系统版本是linux 6版本系统,具体版本:$ed " 
    /etc/init.d/mysqld start
elif [ "X$edition" == "X7"  ]
then
echo -e "INFO `date +%Y-%m-%d_%H:%M:%S` 当前服务器操作系统版本是linux 7版本系统,具体版本:$ed " 
systemctl start  mysqld
fi


if [[ $? = 0 ]]
then
   echo "mysql running!!!"
else
   echo "sorry, pls check out!"
   exit 1
fi

##Mysql数据结构升级
#mysql_upgrade -uroot -p${DB_PASSWORD}
mysql_upgrade -uroot -p${DB_PASSWORD} -S $socket
#/bin/mysql_upgrade -uroot -pPwd_2017 -S $socket

if [[ $? = 0 ]]
then
   echo "mysql_upgrade is done .!!!!!!!"
else
   echo "sorry, pls check out!"
   exit 1
fi

sync;sync;sync
sync;sync;sync
sync;sync;sync
sync;sync;sync
sync;sync;sync
sync;sync;sync
sync;sync;sync
sync;sync;sync
sync;sync;sync
sync;sync;sync
echo 3 > /proc/sys/vm/drop_caches
##查看mysql的版本,并验证服务启动是否正常Mysql数据
mysql -uroot -p${DB_PASSWORD} -e "select version();"
rm -f /root/mysql57_upgrade.sh
cd $UP_SOFT_PATH
rm -f mysql-5.7.38-1.el6.*