mysql 5.7在2015-10-21发布了ga版本,即5.7.9,目前小版本已经到了5.7.12。5.7新增了许多新的feature和优化,接下来一个系列,我们就一起来尝尝鲜。首先这次主要是预览feature的变化以及兼容性问题。后面的系列,会针对重要的feature展开来学习。
mysql.user表中的plugin更改成not null,5.7开始不再支持mysql_old_password的认证插件,推荐全部使用mysql_native_password。从低版本升级到5.7的时候,需要处理两个兼容性问题。
[兼容性]
需要先迁移mysql_old_password的用户,然后进行user表结构的升级:
1. 迁移mysql_old_password用户
mysql 5.7.2之前的版本,是根据password的hash value来判断使用的认证插件类型,5.7.2以后的版本,plugin字段为not null,就直接根据plugin来判断了。新的密码从password字段中,保存到新的字段authentication_string中,password字段废弃处理。
如果user是隐式的mysql_native_password。直接使用sql进行变更:
如果user是隐式的或者显示的mysql_old_password, 首先通过以下sql进行查询:
如果存在记录,就表示还有使用mysql_old_password的user,使用以下sql进行用户的迁移:
2. user表结构升级
通过mysql_upgrade直接进行升级,步骤如下[5.6->5.7]:
stop mysql 5.6实例
替换5.7的mysqld二进制版本
使用5.7启动实例
run mysql_upgrade升级系统表
重启mysql 5.7实例
用户可以通过 <code>alter user 'jeffrey'@'localhost' password expire;</code>这样的语句来使用户的密码过期。
并新增加 default_password_lifetime来表示用户密码自动过期时间,从5.7.10开始,其默认值从0变更到了360,也就是默认一年过期。
可以通过以下两种方法禁止过期:
只需要通过mysql_upgrade升级mysql.user系统表就可以使用密码过期新功能。
用户可以通过以下语法进行账号锁定,阻止这个用户进行登录:
如果mysqld编译使用的openssl,在启动的时候,默认创建ssl, rsa certificate 和 key 文件。
但不管是openssl还是yassl,如果没有设置ssl相关的参数,mysqld都会在data directory里查找ssl认证文件,来尽量打开ssl特性。
不存在兼容性的问题
5.7开始建议用户使用 <code>mysqld --initialize</code>来初始化数据库,放弃之前的mysql_install_db的方式,新的方式只创建了一个root@localhost的用户,随机密码保存在~/.mysql_secret文件中,并且账号是expired,第一次使用必须reset password,并且不再创建test db。
5.7 sql_mode的默认值变更为:
而在5.7之前,sql_mode的默认值都只有mode_no_engine_substitution。
所以在5.7默认的情况下,比如grant不存在的用户的时候,会报一下错误:
必须先使用create user,然后再使用grant user。
默认sql mode发生变更会导致sql的行为不一致。
支持online rename index操作, in_place并且不需要table copy。
变更varchar 类型字段的长度支持inplace方法,但有一个限制,即用于表示varchar字段长度的字节数不能发生变化,也就是支持比如varchar的长度在255以下变更或者255以上的范围进行变更,因为从小于255变更到大于255,其size的字节需要从1个增加到2个。
注意:减少varchar的长度,仍然需要table copy。
因为innodb临时表的数据不再不受redo保护,而redo只保护临时表的元数据,所以大幅提升了临时表的性能。
并且innodb临时表的元数据保存在一个新的系统表中即innodb_temp_table_info,
临时表将建立一个统一的表空间,我们称之为临时表空间,其目录地址可以通过参数innodb_temp_data_file_path来设置。系统在启动的时候,都会新建这个表空间,重启会删除重建。
例如:
并且5.7存储引擎默认都变更成innodb了:
注意: 在开启gtid的情况下,非auto commit或者显示begin的context下,create 或者drop 临时表,仍然和5.6一样:
另外, insert into t select * from t也会遇到错误,不能在一个sql语句中reference两次临时表。
备注: 因为innodb临时表进行了比较大的变动,我们会专门进行一次详细的介绍。
并且支持在spatial data types上建立index,加速查询。
buffer pool dump和load支持一个新的参数innodb_buffer_pool_dump_pct,即dump的比例,并且使用innodb_io_capacity 来控制load过程中的io吞吐量。
从5.7.4开始,innodb_page_cleaners参数可以设置,支持多线程flush dirty page,加快脏块的刷新。
mysql 一直使用double write buffer来解决一个page写入的partial write问题,但在linux系统上的fusion-io non-volatile memory (nvm) file system支持原子的写入。
这样就可以省略掉double write buffer的使用, 5.7.4以后,如果fusion-io devices支持atomic write,那么mysql自动把dirty block直接写入到数据文件了。这样减少了一次内存copy和io操作。
mysql 5.7之前的版本,innodb并不支持分区表,分区表的支持是在ha_partition引擎上支持的,从5.7开始,innodb支持原生的分区表,并且可以使用传输表空间。
mysql_upgrade会扫描ha_partition引擎支持的innodb表,并升级成innodb分区表,5.7.9之后,可以通过命令alter table … upgrade partitioning.进行升级。如果之前的版本大量使用了分区表,要注意使用mysql_upgrade会消耗非常长的时间来升级分区表。
mysql 5.7.5之后,可以online动态调整buffer pool size,通过设置动态的参数innodb_buffer_pool_size来调整,并且根据innodb_buffer_pool_resize_status状态来查看resize的进度,因为resize的过程是以chunk为大小,把pages从一个内存区域copy到另一片内存的。
mysql 5.7.5之前,在recovery的过程中,需要扫描所有的ibd文件,获取元信息, 5.7.5之后,新加了一种redo log类型,即mlog_file_name, 记录从上一次checkpoint以来,发生过变更的文件,这样在recovery的过程中,只需要打开这些文件就可以了。
因为增加了新的log record type,需要安全的关闭5.7之前的实例,清理掉redo。
支持创建表空间,例如
并可以在创建表的时候,指定属于哪个表空间,
因为可以任意指定空间目录,要注意升级过程中,不要漏掉目录。
支持innodb数据文件加密,其依赖keyring plugin来进行秘钥的管理,后面我们单独来介绍innodb加密的方法,并且rds也实现了一种innodb数据文件透明加密方法,并通过kms系统来管理秘钥。例如:
未完待续