MySQL 5.7 学习:功能性能的提升

背景:

继上次介绍 初识 MySQL 5.6 新功能、参数完之后,刚好MySQL 5.7又GA了,在官方测试里看到,MySQL5.7在功能、性能、可用性、安全和监控上又提升了很高。现在看看和MySQL5.6对比,之前介绍了新增配置参数安全相关特性。本文来说明MySQL5.7关于功能和性能提升的方面(持续更新)。

1,功能性能上的提升

1.1:复制功能的提升。

①支持并行复制。slave-parallel-type

5.6开始支持基于库(database)的并行复制,对于只有一个库的,效果不好。5.7开始支持基于组提交(LOGICAL_CLOCK)的并行复制,提高复制的可用性。

②支持多源复制,通过channel支持一个从库复制多个主库。

③支持在线修改REPLICATION FILTERREPLICATE_DO_DB、REPLICATE_IGNORE_DB。通过change replicate filter,需要停止SQL thread,修改完成以后,启动SQL thread。可以参考这篇文章

由于篇幅的原因,后面会另起一篇文章介绍上面功能的细节。

1.2:mysqlpump并行版 mysqldump,也是替换原生 mysqldump 和 mydumper 的。--watch-progress 查看dump进度,--compress-ouptut 压缩,也支持 SSL。 大致的优势如下:(后面会起一篇文章来说明mysqlpump的使用)

  • 支持基于表的并行导出功能(参数–default-parallelism,默认为2,参数–parallel-schemas,控制并行导出的库)
  • 导出的时候带有进度条(参数–watch-progress,默认开启)
  • 支持直接压缩导出导入(参数–compress-output,支持ZLIB和LZ4)

1.3:online alter table初识 MySQL 5.6 新功能、参数里介绍的online ddl的基础上又增加了:

①:在线加主键:当主键列为null字段的时候,5.6建主键需要复制表,5.7可以inplace:

5.6>create table test(id int);
Query OK, 0 rows affected (0.00 sec)
>insert into test values(1),(2),(3);                                                                                                        
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
>alter table test add primary key(id);                                                                                                        Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0      ###copy

5.7>create table test(id int);                                                                                                                 Query OK, 0 rows affected (0.01 sec)
>insert into test values(1),(2),(3); 
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
>alter table test add primary key(id);
Query OK, 0 rows affected (0.03 sec)        ###inplace
Records: 0  Duplicates: 0  Warnings: 0

②:varchar长度变更(加大)支持inplace,需要注意的是有一个限制,即用于表示varchar字段长度的字节数不能发生变化,也就是支持比如varchar的字节长度在255(Latin1)以下变更或者255以上的范围进行变更,因为从小于255变更到大于255,其size的字节需要从1个增加到2个,另一个注意的是不允许inplace字段长度变小:

>show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int(11) NOT NULL,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

>alter table test modify name varchar(64);   ##inplace modify
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

>alter table test modify name varchar(128);  ##inplace modify
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

>alter table test modify name varchar(255);  ##inplace modify
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

>alter table test modify name varchar(256);  ##copy modify,超过了255
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

>alter table test modify name varchar(64);   ##copy modify,长度变小
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

③:支持online rename index操作:

>show create table test\G                                                                                                                   *************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int(11) NOT NULL,
  `name` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

>alter table test rename index name to idx_name;

...

1.4:Undo Log日志的在线回收。innodb undo log占用共享表空间并且无法回收,在5.6的时候可以把undo log分离到独立的表空间,并放到单独的文件目录下,但是其文件大小也不会回收。5.7之后可以在线收缩undo log:需要开启innodb_undo_log_truncateinnodb_undo_tablespacesinnodb_undo_directory参数,当大小超过innodb_max_undo_log_size的大小则会被undo会被标记为可truncate。具体的原理可以看这篇文章。undo log 在整个事务未提交前,undo page是必须强占内存,这会让buffer pool size 收到污染,可以看这个例子说明。

1.5:新增json类型。关于json类型操作的函数参考官方文档MySQL5.7 JSON类型使用介绍,原理介绍见MySQL5.7的JSON 实现

MySQL对支持JSON的做法是在server层提供了一堆便于操作JSON的函数,简单地将JSON编码成BLOB,然后交由存储引擎层进行处理。MySQL 5.7的JSON支持与存储引擎没有关系,MyISAM 存储引擎也支持JSON 格式。MySQL对JSON的支持,至少有两点能够完胜MongoDB:可以混合存储结构化数据和非结构化数据,同时拥有关系型数据库和非关系型数据库的优点;能够提供完整的事务支持。

1.6:generate column。一列由其他列计算而得,可生成索引的虚拟化列。

mysql> create table t(id int,score int,score_ss int as (score*33));
Query OK, 0 rows affected (0.25 sec)

mysql> select * from t;
Empty set (0.00 sec)

mysql> select * from t;
Empty set (0.00 sec)

mysql> insert into t(id,score) values(1,10);
Query OK, 1 row affected (0.03 sec)

mysql> select * from t;
+------+-------+----------+
| id   | score | score_ss |
+------+-------+----------+
|    1 |    10 |      330 |
+------+-------+----------+

建表标准的语法:
CREATE TABLE `t` (
  `id` int(11) DEFAULT NULL,
  `score` int(11) DEFAULT NULL,
  `score_ss` int(11) GENERATED ALWAYS AS ((`score` * 33)) VIRTUAL/STORED,
  KEY `idx_score_ss` (`score_ss`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 MySQL5.7支持两种generated column,即virtual generated column和stored generated column,前者只将generated column保存在数据字典中(表的元数据),并不会将这一列数据持久化到磁盘上;后者会将generated column持久化到磁盘上,而不是每次读取的时候计算所得。很明显,后者存放了可以通过已有数据计算而得的数据,需要更多的磁盘空间,与virtual column相比并没有优势。因此,在不指定generated column的类型时,默认是virtual column,并且为generate column创建索引可以提高性能。 

1.7:InnoDB 全文索引的加强:支持中文分词。InnoDB默认的全文索引parser非常合适于Latin,因为Latin是通过空格来分词的。可以看这篇文章的介绍,但对于像中文,日文和韩文来说,没有这样的分隔符。一个词可以由多个字来组成,所以我们需要用不同的方式来处理。在MySQL 5.7.6中我们能使用一个新的全文索引插件来处理它们:n-gram parser。关于n-gram的介绍和使用可以看这篇文章

在全文索引中,n-gram就是一段文字里面连续的n个字的序列。例如,用n-gram来对”信息系统”来进行分词,得到的结果如下:

posted @ 2016-07-19 14:26  jyzhou  阅读(12634)  评论(1编辑  收藏  举报