两种升级方式
- In-Place Upgrade: Involves shutting down the old MySQL version, replacing the old MySQL binaries or packages with the new ones, restarting MySQL on the existing data directory, and running mysql_upgrade.
- Logical Upgrade: Involves exporting existing data from the old MySQL version using mysqldump, installing the new MySQL version, loading the dump file into the new MySQL version, and running mysql_upgrade.
主从的升级:
- 主从想都替换二进制安装包为最新版本
- 停从,通过mysql_upgrade升级后,加参数 --skip-slaves-start 进行启动
- 加参数 --skip-networking重启主,拒绝来自应用的TCP/IP的连接,关闭binlog,执行mysql_upgrade,然后重启
- 注意点:在关闭服务时加参数 --innodb_fast_shutdown=0 (slow shutdown),会将所有提交的事务对应的脏页刷新到数据文件中,默认是1(fast shutdown 参考文献:http://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_fast_shutdown)
MySQL5.6版本到5.7版本的更新包括一些不兼容的特性,在升级到5.7之前,我们需要知道这些不兼容的特性并手动更新,在其中涉及到REPAIR TABLE和USE_FRM选项的指令一定要在更新版本之前完成。
配置项更新
- --early-plugin-load
MySQL5.7.11,此参数的默认值为keyring_file(是一个二进制文件的插件),InnoDB表空间在初始化InnoDB之前需要此插件来加密,但是MySQL5.7.12及以后此参数默认为空,所以5.7.11升级到5.7.12后,如果已经在之前的版本中使用此插件对InnoDB表空间进行了加密,在开启服务时需要指定参数 --early-plugin-load
系统表
MySQL5.6中INFORMATION_SCHEMA 中存在系统变量和状态变量的表,show variables 和show status也是基于此库中的表,在5.7.6时被Performance Schema也存在这四张表,show 语句开始基于Performance Schema中的表,如果show_compatibility_56参数开启,则兼容5.6
下面的测试库是从MySQL5.6版本中直接物理恢复到MySQL5.7环境下的
mysql> select version(); +------------+ | version() | +------------+ | 5.7.10-log | +------------+ 1 row in set (0.00 sec)
mysql> show variables like ‘%56%‘;
ERROR 1146 (42S02): Table ‘performance_schema.session_variables‘ doesn‘t exist
mysql> use performance_schema;
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> show tables like ‘%variable%‘;
Empty set (0.00 sec)
mysql> set global show_compatibility_56=ON;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like ‘%56%‘;
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| sha256_password_proxy_users | OFF |
| show_compatibility_56 | ON |
+-----------------------------+-------+
2 rows in set (0.00 sec)
- 使用mysqld --initialize (or mysqld --initialize-insecure).初始化实例
sql mode
ONLY_FULL_GROUP_BY
, STRICT_TRANS_TABLES
, NO_ENGINE_SUBSTITUTION
默认开启
如以下sql在only full group by下,name非聚集字列,如果不在乎返回的address的值是否准确,则可以使用ANY_VALUE函数,这样address字段就无需满足full group by 出现在group by 中
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
系统表的改变
mysql.user的password字段在5.7.6中已去除,认证信息记录在authentication_string中,运行in-place upgrade 迁移password列值到authentication_string
如果是通过logical upgrade,需要注意:
- You must include the
--add-drop-table
option - You must not include the
--flush-privileges
option
server端的更改
MySQL5.7.5开始mysql_old_password 插件被移除
secure-auth 系统变量仅支持值1
--skip-secure-auth 选项被弃用
old_password系统变量的值1(将密码hash为41位的hash值)不再被允许
old_password ()函数被移除
字段类型YEAR(2)被更改为YEAR(4)
MySQL5.7.2开始mysql.user系统表中的plugin字段不允许为空,运行mysql_upgrade会进行如下操作
UPDATE mysql.user SET plugin = ‘mysql_native_password‘ WHERE plugin = ‘‘ AND (Password = ‘‘ OR LENGTH(Password) = 41); FLUSH PRIVILEGES;
需要注意sql_mode的变更,如:
mysql> SET sql_mode = ‘‘; Query OK, 0 rows affected (0.00 sec) mysql> CREATE TABLE t (d DATE DEFAULT 0); SET sql_mode = ‘NO_ZERO_DATE,STRICT_ALL_TABLES‘; INSERT INTO t (d) VALUES(DEFAULT);Query OK, 0 rows affected (0.52 sec) mysql> SET sql_mode = ‘NO_ZERO_DATE,STRICT_ALL_TABLES‘; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> INSERT INTO t (d) VALUES(DEFAULT); ERROR 1292 (22007): Incorrect date value: ‘0000-00-00‘ for column ‘d‘ at row 1
SQL变更
MySQL5.7.5之前GET_LOCK()在执行第二次的额时候会释放前面获得的锁,在此版本以后支持同时获得多个锁,如:
mysql> select version(); +------------+ | version() | +------------+ | 5.6.33-log | +------------+ 1 row in set (0.00 sec) mysql> SELECT GET_LOCK(‘lock1‘,10); +----------------------+ | GET_LOCK(‘lock1‘,10) | +----------------------+ | 1 | +----------------------+ 1 row in set (0.00 sec) mysql> SELECT GET_LOCK(‘lock2‘,10); +----------------------+ | GET_LOCK(‘lock2‘,10) | +----------------------+ | 1 | +----------------------+ 1 row in set (0.00 sec) mysql> SELECT RELEASE_LOCK(‘lock2‘); +-----------------------+ | RELEASE_LOCK(‘lock2‘) | +-----------------------+ | 1 | +-----------------------+ 1 row in set (0.00 sec) mysql> SELECT RELEASE_LOCK(‘lock1‘); +-----------------------+ | RELEASE_LOCK(‘lock1‘) | +-----------------------+ | NULL | +-----------------------+ 1 row in set (0.00 sec)
返回null说明此锁已经被释放了
参考文献:
http://dev.mysql.com/doc/refman/5.7/en/upgrading-from-previous-series.html