本文将和大家一起分享下5.7的新特性,不过我们要先从即将被删除的特性以及建议不再使用的特性说起。根据这些情况,我们在新版本及以后的版本中,应该不再使用,避免未来产生兼容性问题。
本文是基于MySQL-5.7.7-rc版本,未来可能 还会发生更多变化。
1、即将删除的特性
1.1、InnoDB monitoring features,详见:WL#7377(访问地址:http://dev.mysql.com/worklog/task/?id=7377,下面的其他WL,可以自行替换)
【建议】可以动态修改 innodb_status_output、innodb_status_output_locks 两个参数的值打印相关信息,或者直接查看INFORMATION_SCHEMA下的相关表。
1.2、old-password,4.1之前的就密码认证模式已经禁用,old_passwords参数不可用,
【建议】尽快升级旧密码串,同时升级MySQL版本,不要告诉我,你还在用4.1甚至更早的版本。
1.3、部分SQL语法不可用
1.3.1、ALTER TABLE … IGNORE。
1.3.2、INSERT DELAY特性,但保留这个语法。
1.3.3、ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_DATE, NO_ZERO_IN_DATE SQL MODES 等几个SQL MODE合并到STRICT中。不过可能会导致replication失败,所以还在考虑中。
1.3.4、不再支持YEAR(2),建议尽快升级成YEAR(4)。
【建议】尽可能使用标准SQL语法,不再使用MySQL特有的,或者不是那么严格要求的语法,避免以后版本升级遇到更多麻烦。
1.4、一些参数不可用
1.4.1、不再支持一些指令的简短写法,必须要求写全了,例如mysqldump –compr表示 mysqldump –compress,以后必须将整个参数写完整。
1.4.2、删除timed_mutexes。
1.4.3、不能再禁用InnoDB引擎,因为系统表也都改成InnoDB了。
1.4.4、性能提升有限,删除innodb_use_sys_malloc、innodb_additional_mem_pool_size。
1.4.5、意义不大,删除innodb_mirrored_log_groups。
1.4.6、已经有新的系统参数代替了,删除innodb_file_io_threads。WL#7149
1.4.7、删除系统参数storage_engine,改用default_storage_engine。WL#7148
1.4.8、删除mysql_upgrade中的–basedir和–datadir系统参数。WL#7010
1.5、一些客户端工具
mysqlaccess、mysql_convert_table_format、mysql_fix_extensions、mysql_find_rows.sh、mysql_setpermission、msql2mysql、mysqlbug、mysql_zap and mysql_waitpid、mysqlhotcopy将不再使用。
【建议】没什么好说的,顺应潮流跟上新版本吧,该放弃的就放弃,不要抱残守缺了,这些工具也基本上都用不上的。
2、预计取消的特性
2.1、客户端交互协议中,EOF协议包不建议再使用了,建议改成OK协议包。
2.2、不建议使用SHOW PROFILE指令,或直接从INFORMATION_SCHEMA.PROFILING中查看,建议利用PERFORMANCE_SCHEMA中的几个视图查看。WL#6802
2.2、基于DES算法的加解密函数不建议使用, 取而代之的是用基于AES的加解密函数。
2.4、同上,还不建议使用ENCODE()/DECODE()函数。WL#6984
2.5、采用ALTER USER来为用户修改密码,不建议再使用SET PASSWORD修改密码。
2.6、和InnoDB相关的4个系统参数innodb_large_prefix、innodb_file_format、innodb_file_format_check、innodb_file_format_max不再建议使用。
2.7、不再建议在EXPLAIN后面加上EXTENDED/PARTITIONS关键字。
2.8、不再建议使用collation_database、character_set_database系统参数。
2.9、不再建议使用sync_frm系统参数。
2.10、不再建议使用@@session.gtid_executed系统变量。
3、安全性
a、用户表mysql.user的plugin字段不允许为空,默认值是mysql_native_password,而不是mysql_old_password,不再支持旧密码格式;
b、增加密码过期机制,过期后需要修改密码,否则可能会被禁用,或者进入沙箱模式;
c、使用mysql_install_db初始化时,默认会自动生成随机密码,并且不创建除root@localhost 外的其他账号,也不创建test库;
在5.7中,推荐使用mysqld –initialize对数据库进行初始化,在初始化时如果加上–initial-insecure,则会创建空密码的 root@localhost 账号,否则会创建带密码的 root@localhost 账号,密码直接写在 log-error 日志文件中(在5.6中是放在~/.mysql_secret里);
在5.7中可以对普通用户进行unlock及lock操作。
4、SQL_MODE
默认启用STRICT_TRANS_TABLES模式;
对ONLY_FULL_GROUP_BY模式实现了更复杂的特性支持,并且也被默认启用;
其他被默认启用的sql mode还有NO_ENGINE_SUBSTITUTION。
在5.6中对一个10字符长度的VARCHAR列写入15个字符,会自动截断并给出告警,而在5.7,则直接抛出错误了。
5、增强了InnoDB引擎的一些功能
优化了DDL操作,在涉及到InnoDB临时表时,性能显著提升;
在5.6及以前,InnoDB临时表的元数据存储在InnoDB系统表里,在5.7中,临时表的信息及元数据都存储在新多出来的表INNODB_TEMP_TABLE_INFO中;
在5.7中,InnoDB临时表会存储在一个非压缩的、单独的表空间中,每次启动MySQL服务,都会自动创建该表空间,默认存储在DATADIR下,其路径由参数innodb_temp_data_file_path指定;
支持在线(INPLACE)增加VARCHAR列的长度。不过0-255长度是一个区间,256以上是另一个区间,不能跨越255这个坎,比如把长度从100扩展成1000(因为255长度以内额外用1个字节表示,大于255长度则需要额外2个字节表示);
不支持在线缩小VARCHAR的长度 ;
支持innodb_page_cleaners选项可设置多个page cleaner线程提高脏页刷新效率 ;
可通过设置innodb_undo_log_truncate等选项自动删除不用的undo log ;
加强InnoDB read-only模式的性能 ;
在5.7中,可以创建一个普通的表空间:
CREATE TABLESPACE tablespace_name
ADD DATAFILE ‘file_name.ibd’
[FILE_BLOCK_SIZE = n]
6、优化online操作,例如修改buffer pool、修改索引名(非主键)、修改REPLICATION FILTER、修改MASTER而无需关闭SLAVE线程等众多特性。
可以在线修改buffer pool对DBA来说实在太方便了,实例运行过程中可以动态调整,避免事先分配不合理的情况,不过 innodb_buffer_pool_instances 不能修改,而且在 innodb_buffer_pool_instances 大于 1 时,也不能将 buffer pool 调整到 1GB 以内,需要稍加注意。
如果是加大buffer pool,其过程大致是:
1、以innodb_buffer_pool_chunk_size为单位,分配新的内存pages;
2、扩展buffer pool的AHI(adaptive hash index)链表,将新分配的pages包含进来;
3、将新分配的pages添加到free list中;
如果是缩减buffer pool,其过程则大致是:
1、重整buffer pool,准备回收pages;
2、以innodb_buffer_pool_chunk_size为单位,释放删除这些pages(这个过程会有一点点耗时);
3、调整AHI链表,使用新的内存地址。
实际测试时,发现在线修改 buffer poo 的代价并不大,SQL命令提交完毕后都是瞬间完成,而后台进程的耗时也并不太久。在一个并发128线程跑tpcc压测的环境中,将 buffer pool 从32G扩展到48G,后台线程耗时 3秒,而从 48G 缩减回 32G 则耗时 18秒,期间压测的事务未发生任何锁等待。
-- 演示1:从 1G 扩大到 16G
-- 演示2:从 16G 缩减到 1G
SET GLOBAL innodb_buffer_pool_size = 51539607552;
SET GLOBAL innodb_buffer_pool_size = 1073741824;
再来看下在线修改非主键索引名,直接用 ALTER TABLE RENAME INDEX 语法即可。
【新特性实践】
例如下面的SQL语法:ALTER TABLE orders RENAME INDEX idx1 TO idxxx1;
7、在5.7中,可以在INFORMATION_SCHEMA里面的表中查看MySQL的系统参数
8、支持一个表上有多个触发器,这样一来,原先已有触发器表也可以支持用pt-osc 了
9、支持对在线某个连接直接查看执行计划,比如EXPLAIN FOR CONNECTION 1024
10、新增log_syslog选项,可将MySQL日志打印到系统日志文件中
11、在MySQL 5.6以前,在客户端CTRL+C后会直接退出啊MySQL客户端,这一点比较恶心,在5.7以后不会退出客户端而是终端当前的操作
12、新增一个比较好的功能,就是在CREATE | ALTER TABLE时,可以在某张表已有列的基础上,对新增的列进行运算:
CREATE TABLE triangle (
sidea DOUBLE,
sideb DOUBLE,
sidec DOUBLE AS (SQRT(sidea * sidea + sideb * sideb))
);
INSERT INTO triangle (sidea, sideb) VALUES(1,1),(3,4),(6,8);
mysql> SELECT * FROM triangle;
+——-+——-+——————–+
| sidea | sideb | sidec |
+——-+——-+——————–+
| 1 | 1 | 1.4142135623730951 |
| 3 | 4 | 5 |
| 6 | 8 | 10 |
+——-+——-+——————–+
13、支持多源复制,可以把多个MASTER的数据归并到一个实例上,如果是同一个表的话,会存在主键和唯一索引冲突的风险,需要提前做好规划。
14、支持多线程复制。
支持多线程复制(Multi-Threaded Slaves, 简称MTS),在5.6版本中实现了SCHEMA级别的并行复制,不过意义不大,因为我们线上大部分实例的读写压力基本集中在某几个数据表,基本无助于缓解复制延迟问题。倒是MariaDB的多线程并行复制大放异彩,有不少人因为这个特性选择MariaDB。
MySQL 5.7 MTS支持两种模式,一种是和5.6一样,另一种则是基于binlog group commit实现的多线程复制,也就是MASTER上同时提交的binlog在SLAVE端也可以同时被apply,实现并行复制。关于MTS的更多详细介绍可以查看姜承尧的分享 MySQL 5.7 并行复制实现原理与调优。
值得一提的是,经过对比测试,5.7采用新的并行复制后,仍然会存在一定程度的延迟,只不过相比5.6版本减少了86%,相比MariaDB的并行复制延迟也小不少。