MySQL 升级说明

MySQL 升级说明

1.为什么升级

在没有充分测试前, 升级MySQL,尤其是主版本升级会存在很大的风险, 可能系统表或存储引擎组织方式做了更新, 也可能是参数或默认值信息做了改动, 这些都可能引起应用的中断甚至Server端的崩溃; 不过升级的好处也是很大的,比如想使用新版的功能特性,更好的性能,对固态盘的支持或者已经修复的bug等; 当然一般来说bug和性能问题会促使我们做一些小版本或大版本的升级, 在没有遇到这两个问题之前, 个人不建议对正在稳定使用的MySQL进行升级, 即便新版有更好的功能或性能。

2.升级的方式

我们通俗的将版本升级分为主版本升级(大版本升级)和次版本升级(小版本升级):

MySQL 5.1 升级到 MySQL 5.5 称为主版本升级;
MySQL 5.5.23 升级到 MySQL 5.5.33 称为次版本升级;

主版本之间的改动一般表现为系统表或参数信息的变更, 索引或行记录的组织方式也可能出现变更;次版本之间的改动一般表现为bug的修复, 同样接口或功能之间性能方面的提升。从这方面来看升级一般分为两种方式:

SQL导出(dump):可以使用mysqldump或mydumper工具完成主版本的升级, 从低版本导出SQL数据, 再导入到高版本中;
basedir替换:在不改动MySQL datadir的前提下,更换启动脚本的basedir,再使用mysql_upgrade来完成次版本之间的升级;

mydumper

主版本之间升级的时候可以关注官方的upgrading信息,比如:

upgrading-from-previous-series

3.主版本升级

再次申明主版本升级是存在风险的, 升级之前多关注官方手册中提到的说明,尤其是关于不兼容相关的. SQL导出是相对安全的方式, 但也是最慢的升级方式, mysqldump或mydumper被称为逻辑备份方式, SQL语句等通过明文方式导出, 最后再导入到新版本中。但是对于大数据量的库而言,比如100G, 1T等,这种方式是很耗时的,不过换个角度来看dump和restore_dump完成了表的优化,也可能整理了表空间的碎片,相对于原库而言节省了一些磁盘空间, 这种情况在更新(update/delete)频繁的InnoDB表中会明显些。

理论上,SQL导出需要通过以下几步:

1. 从低版本导出低版本的权限信息; # 不要使用dump,因为高版本可能有系统表的更新, 可以使用percona 的pt-show-grants工具导出SQL授权形式的语句
2. 从低版本导出数据信息; # 5.1版本需要排除mysql和information_schema库; 5.5版本还要排除performance_schema库
3. 导出权限信息到高版本;
4. 导出数据信息到高版本;

以5.5升级到5.6版本举例如下:

1)导出5.5版本的权限信息

# pt-show-grants --socket=/web/mysql/data/3300.sock >/tmp/grants.sql

2)mysqldump导出5.5版本的数据信息

需要排除掉mysql, information_schema和performance_schema三个库:

# mysql -Bse 'use information_schema;select distinct(table_schema) from tables where table_schema not in ("mysql","information_schema","performance_schema")' >/tmp/db_schema.txt
# for x in `cat /tmp/db_schema.txt`; do echo $x; mysqldump --routines --events --single-transaction --databases $x >/tmp/$x.sql;done

3)关闭5.5版本的实例:

service mysqld_5.5 stop

4)修改好my.cnf配置文件中的参数信

高版本中可能弃用或修改了一些参数。移动导出的文件到高版本的主机中;启动高版本实例:

service mysqld_5.6 start

5)将权限信息导入5.6版本:

mysql -S /web/mysql/data/3300.sock < /tmp/grants.sql"

6)导入数据信息到5.6版本:

# for x in `cat /tmp/db_schema.yxy`; do echo $x; mysql -S /web/mysql/data/3300.sock > /tmp/$x.sql;done

如果数据较大, 可以增加 max_allowed_packet 参数, mysql导入的时候也可以增加 max_allowed_packet 参数的值. 这种方式相当于重建了一遍5.5版本的数据库信息, 虽然比较慢但却是最保险的做法,而且不同MySQL分支版本之间进行升级也会避免很多错误出现.

4.次版本升级

替换方式节省了很多时间, 但也可能出现一些细微的错误, 我们以 5.5.23 升级到 5.5.40 为例说明次版本升级的过程.

1)关闭5.5.23版本的实例:

# cat init scipts
## defines BASEDIR required
BASEDIR=/opt/MySQL-Server-5.5.23

# service mysqld_5.5.23 stop

2)修改basedir信息

## defines BASEDIR required
BASEDIR=/opt/MySQL-Server-5.5.40

3)启动新版本实例, 并使用mysql_upgrade检测并更新需要的操作:

# service mysqld_5.5.40 start
# cd /opt/MySQL-Server-5.5.40/bin
# ./mysql_upgrade --host=127.0.0.1 --port=3300 /web/mysql/data/3300.sock -p
Enter password: 
Looking for 'mysql' as: ./mysql
Looking for 'mysqlcheck' as: ./mysqlcheck
Running 'mysqlcheck' with connection arguments: '--host=127.0.0.1' '--port=3300' 
Running 'mysqlcheck' with connection arguments: '--host=127.0.0.1' '--port=3300' 
mydb.log_record                                    OK
mydb.user_login_1                                  OK
mydb.user_login_2                                  OK
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.general_log                                  OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.host                                         OK
mysql.ndb_binlog_index                             OK
mysql.plugin                                       OK
mysql.proc                                         OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.servers                                      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
Running 'mysql_fix_privilege_tables'...
OK

如果不希望更新数据信息可以增加 -s 选项,仅更新系统表:

-s, --upgrade-system-tables 
                      Only upgrade the system tables do not try to upgrade the
                      data.

5.注意事项

所有正式更改前都需要进行严格的测试, 应用程序也需要测试,一些微小差异可能会引起服务不可用, MySQL官方各版本的 release notes 手册详细列出了每次更新所做的改动, 可以参考手册信息明确版本之间的变化,如5.6版本 5.6-index; percona的 pt-upgrade 工具可以帮助我们测试一些指定的sql语句是否会在新版本中出现问题. 不要从5.0直接升级到5.6, 大版本之间的变化是巨大的, 索引和数据组织方式可能已经更新了多个版本, 个别的SQL语法也可能有所更新, 其互相之间并不兼容, 可以参考主版本升级的方式进行大版本的升级.