MySQL8.0毕竟一个非常大版本的改动,我们直接从5.7一下跳到8.0了,版本规则的变化,我们对产品研发过程之中会有一些跟以往不一样的路径。
我今天演讲主要分这几个部分,第一个是功能方面的改进,讲的主要是MySQL8.0 里面 InnoDB,我只讲InnoDB,因为我是InnoDB组的,在MySQL8.0里面 InnoDB提供了哪些功能。
第二部分,性能改进,8.0里面InnoDB方面做了些什么事情。
还有些未来展望,我今天讲的这些东西,今天讲的这些功能和性能的改进,只是已存在于我们8.0的代码里面的功能。将来8.0里面可能还会增加一些新的功能,我们在未来的展望里面去做一些介绍。
第一部分,功能的改进,功能改进第一个最大的改动,在8.0里面,我们在InnoDB把数据字典进行重构,大家应该知道数据字典是什么,就是表结构,你的用户定义,所有的跟DDL相关放到数据字典里面去。
我们为什么要做这个重构呢?因为在8.0以前,5.7、5.6之前更早的版本,它存在很大问题是什么?MySQL有两套数据字典,这两套数据字典,一套是放在MySQL层,一套是放在InnoDB里头。
MySQL层,它把这些数据字典放在什么地方呢?就是放在文件里头,.frm这些里头。
InnoDB放在哪里,InnoDB放在自己的数据表里头。这样会有什么问题呢?
第一个,它不支持原子操作,也就是的DDL不能做原子操作,而InnoDB的表是可以做。不支持原子操作由此引生什么,两套字典不匹配。
同一张表的表结构,有可能在MySQL一种结构,而到InnoDB里面另外一种表结构,所以会导致第二个问题数据字典不一致。
第三个,处理DDL并发的时候,我们需要非常的小心,因为两套数据字典有两套数据字典的并发不同机制。
InnoDB里面是用dict_sys::mutex这个同步,但是MySQL那层用MDL,这样比较容易产生死锁,因为有两种不同的锁机制混在一起。
最后一个,有可能导致的问题是崩溃的时候表没法恢复,表结构已经损坏了。
这件事情,我们很久以来一直想做,一直到8.0里才把这个事情做完。我们在8.0里面进行了这样的改动之后,得到了这样一些好处。
首先,数据字典只有一份。第二个,支持原子操作,不会再有不一致的情况。第三个,我们支持了事务型的DDL,也就是你做一个DDL支持所有事务的ACID的特性。
第四个,数据字典只存放在InnoDB里头。刚才我提到的我们用同一套锁机制来管理这个数据字典的并发控制,也就是MDL管理它。而.frm文件,我们基本上已经把它去掉了,在8.0里头可能还有残留的.frm文件,但基本上把它干掉了。
所以这个是我们在8.0里面做的比较大,而且比较基础的事情。
但是可能大家没有太多的感觉,因为你们平时也不会碰到这块问题,但是一旦碰到的话,可能就是一个很大的问题,因为你的表损坏了,表结构损坏了。
为了大家将来不要出类似的问题,所以我们做了这样一个非常基础性的改进。
这是一个示意图,在8.0里头我们直接去写,直接去访问这个InnoDB这些数据字典,像原来5.7访问FRM文件,也同时访问InnoDB系统表,这张表比较直观告诉大家原来数据字典和现在数据字典怎么样的情况。
刚刚我讲完第一个比较重大的改进,值得一提的是这个重大的改进是中国团队最终完成的,我们大概是四个中国人把这个大功能做完了。
快速加字段这个功能这个也是我们中国的小伙伴做的,不过不是官方,而最初的patch是腾讯团队提供的,他们提供最初的patch,我们把它改进之后合并我们版本里头,这个功能非常实用,可能大家经常会用到。
很想现在应用系统表里加一个字段,但是原来呢?加字段要等,可能等很长时间,它会需要建一张新的表,然后把原来的数据拷过去。
现在不用了,我们快速加字段不需要重建表,也不需要拷贝数据。
发一个加字段指令,瞬间返回,为了能够做到这个,我们改了页结构,改了数据的页结构,能够告诉我们,你当前加过字段记录,还是没有加过字段记录,我们针对两个不同版本有不同的处理方式,这是这个功能达到的目的,这个非常实用,大家将来用8.0会经常用到这个功能。
第三个功能,官方安全方面,加密,这个功能是之前5.7里面加密功能的延续。5.7版本,我们提供了表数据的加密,大家都知道5.7里面有这个。
我们在后续的功能实现里头,我们把redo-log和undo-log进行加密,如果不加密的话,我要插某个等于张三名字进去,这个数据进到这两个log的时候,它也会含有张三这个字段的信息,对不对?
所以我们要对这两个进行加密就更安全了,让你拿到了它的数据也没用对不对,因为它是加密过的。
通用表,共享表空间的应该已经做完了,可能会在新的8.0版本里面看到,我有一些共享表空间,大家应该知道可以把很多张表建在一个表空间里头。之前我们的加密,只支持加密一个表一个IBD文件情况,现在对于这个也能够进行加密了。
接下来一个功能,Memcached和自增列的改进,大家了解Memcached,它是一个缓存系统,InnoDB的Memcached plugin,可能大家不是特别熟悉,我了解下来可能大家用这个功能比较少。
这个插件提供直接访问InnoDB的方式,而不需要经过上层解析这一套东西,而直接API访问InnoDB里面东西。
在8.0里面,我们对这个Memcached plugin进行了增强,就是我们现在可以支持multiple get和范围查询。
原来通过这个查找数据只能单点查,现在你输一个范围,我要找大于5,小于100的所有数据,所有值查出来,现在就可以做到。
第二个功能,自增列的改进,原来自增列的当前值,我们是怎么记的呢?其实我们不记,我们不知道它的自增列现在最大值多少。
我们怎么知道呢?每一次重新启动或者打开表的时候才得到当前自增列最大值是多少,这会造成一些问题,有时候自增列会重复或者看到一些别的。
我们现在把它放到数据字典里面去,不会再通过这种方式再找自增列当前值。
还有information schema的改变,比如加入新的信息来访问当前的,知道当前schema状态,这个不讲了。
我刚才讲了8.0里面比较重要一些功能方面的改进,展望里面我会讲可能提供另外更多重要的功能。
接下来,第二大部分,我讲一下InnoDB在8.0里头做了哪些性能方面的改进。
第一个最重大性能方面改进,redo log的并行写。原来写redo log是InnoDB的瓶颈,为什么呢?因为大家在做DML都要写redo log。
写redo log,高并发的情况下,大家都要写redo log就会产生冲突,这个时候你的写入就没有那么顺畅了,对不对。
他们会堵在什么地方呢?他们会堵在写log buffer这一步上头,log buffer它是有个大的mutex在保护这个log buffer,在8.0里头我们把这个去掉了。
现在要去写redo log,我们通过一种算法,就是不需要锁的算法,预先分配需要某一块log buffer给一个,通过LSN分配这些log buffer。
这样它就不会抢log buffer,预先分配一部分log buffer,你只需要往这部分log buffer写就可以了,这块把写redo log瓶颈给极大的改善了。
大概改善有多少,大家可以去看我们测试同事部门的网站,他的专门网站把测试结果剖出来,至少高并发情况下50%以上提升性能。
尤其随着你的线程数不停地增长,以前线程数越多,达到一定峰值性能曲线往下降,现在还会往上升,尤其128个线程并发的时候还会往上升,大家可以看一下那个曲线。
第二部分性能改进是这样三个,第一个是基于代价的优化,提供了一些统计信息,比如说索引里面在内存中的页,信息提供给优化器,让优化器去看我当前用哪个索引比较合适。
还有一个是percona提供一个,把buffer pool移除拆分成好几个。还有阿里的优化了redo log的patch。
还有就是这个按照table id来做purge,我们按照table id进行分组,多个线程情况下减少冲突。
在做删除的时候,二级索引不是马上给删掉,会打一个标记一下这个索引记录是被删掉的,这样做的好处我可以提高删数据的速度。
但是这些数据什么时候被删掉呢,由这个purge线程来做,查找所有二级索引记录里面被打了标记的记录,哪些可以被删掉,然后它再把这些数据都删掉。
原来我们没有这个功能之前,大家都混在一起的,速度就会比较慢,现在我们按照这个进行分组,这样做的时候速度比较快,对前台线程影响也会少很多。
下面这两个是,死锁检测可以动态调整,我估计比较少人调整这个死锁检测,这个东西可能对于性能影响也不是特别大,比较极端的情况下才会有性能方面的影响。
除了这两大块之外,我们将来可能 8.0 里面加入的功能,还有第一个是更好的表空间的管理,我们的表空间可能会越来越像Oracle。
比如为表空间加入版本控制也是,不同格式的表,不同格式的页,我可以放在同一个表空间里头,这样将来可能会提供的功能。
还有一个表空间将自我描述,你在表空间拿到另外一个地方去的时候,你需要把你的数据字典定义都拿出来对不对,不然你拿过去不知道这边表结构什么样。
我们将来可能会通过SDI,把你当前的表结构信息放到这个文件里面,用这个JSON格式的文件拷到目标地去,通过这个JSON文件就知道这个表到底是什么样的结构。
另外,还有为文档和JSON提供更好的存储支持,这个为了应对MangoDB,它在处理大文本数据或者大的BLOB时候,比MySQL有更大的优势,在8.0也增强了对这块支持。
比如更灵活处理BLOB对象,已经放到8.0新的版本里头,原来修改一个BLOB时候,改一个字段把整个BLOB对象重新写一遍,现在就不需要了。我如果只改其中一部分的话,可能只用改很少的一部分数据就可以了。
将来还有这样的性能优化,对于事物生命周期优化,不必要的去掉,MVCC可能进行一些改进,死锁检测也会进行一些改进。还有文件系统的变化,做冲突的保护。
这底下是下载的连接等方面,还有最重要的,你们想知道8.0的最新性能测试报告,你们去访问我同事的网站,你可以看到8.0的最新TPS、QPS是多少。
有了好的工具,还要根据业务进行数据库优化!尤其是大型数据库如何提升执行效率,满足业务需求!