是时候使用MySQL 8了!
了解数据库技术发展的同学知道,数据库有个重要的发展方向就是和硬件紧密集成,把一些软件干的活“下放”给硬件去做,能极大地提升性能。
比如TeraData的大数据一体机,在硬件,操作系统,存储等方面专门为数据分析做了优化,性能自然强大。不过这些硬件提供的加速能力不是通用的服务,必须得单独购买才行。
最近看到亚马逊云科技在2022年11月的re:Invent上发布了两个云数据库的功能,一个是“优化写入”,一个是“优化读取”,发现它们就是利用Amazon Nitro系统,和底层硬件做了集成,让MySQL的写入性能提升了2倍,读取性能提升了50%。
优化写入解决的是MySQL用软件实现的Double Write Buffer的问题, 说的是MySQL缓冲区的数据页是16 Kb,文件系统的页通常是4 Kb,它们两个不匹配。
当MySQL缓冲区的16 Kb的页需要写入文件系统时,需要分4次才行,那自然会出现类似这样的问题:写了3次以后掉电了,那最后4 Kb的数据就丢失了。
MySQL的解决办法很粗暴,在硬盘上开辟一个2M的文件缓冲区,内存中缓冲区的数据在写入真正的数据文件之前,先写入这个文件缓冲区,写成功了,再往真正的数据文件去写。
这样再出现写入12 Kb就断电,真正的数据文件中虽然还是有4Kb是丢失的,但是可以从那个2M的文件缓冲区找到原始数据进行恢复,因为那里写成功了,是完整的。
由于需要往硬盘写入两次,所以叫做Double Write,这个办法虽然可以工作,但是说实话,挺别扭的,因为断电这种极端情况很罕见,绝大部分时间这个2M的文件缓冲区没用,白白多写了一次硬盘,要知道硬盘速度可比内存访问慢多了。
我们很容易就会想到:就不能把MySQL缓冲区的16 Kb数据一次性地写入硬盘吗?这样不就省事了吗?
通过使用Amazon Nitro系统中的Torn Write Prevention技术,亚马逊云数据库实现了优化写入数据,只需一步即可安全写入 16Kb 数据页,完全不用复杂的Double Write了。
简洁的系统必然带来更高的效率,优化写入让写入事务吞吐量提高多达 2 倍,且无需额外费用,非常适合写入密集型应用,比如数字支付,金融交易,在线游戏等等。
这就是软件和硬件结合带来的威力。
有了优化写入,自然有对应的“优化读取”。
在云数据库中,计算节点和存储节点一般是分离的。我们在做数据分析的时候经常需要很复杂的查询,涉及的数据会有上千万条,还需要分组,计算,排序等,这时候MySQL就会形成临时对象,当临时对象大到一定程度,就需要形成临时的表空间,移到硬盘上来存储了。
上图中,Amazon RDS实例是计算节点,Amazon Elastic Block Store(Amazon EBS)是存储节点,这个临时的表空间(上图红框所示)是存储在Amazon EBS上,由于是分布式的存储,访问就会有一定的延迟。
现在通过软硬一体化,在Amazon RDS实例上挂载一张NVMe的SSD存储,它针对低延迟、高随机 I/O 性能和高顺序读取吞吐量进行了优化。
在软件层面,让临时表空间转移到这个SSD存储卡中,计算节点直接访问本地存储,这速度立刻飞起。
对于复杂查询,“优化读取”的加速效应非常明显,可以提升50%, 查询越大越复杂,优化效果越好。
我到亚马逊云科技的网站上去看了一下,想要开启“优化写入”和“优化读取”,充分发挥底层硬件的功能,需要RDS MySQL 8及以上的版本。
这也很正常,MySQL 8.0 2018年4月19日正式GA ,已经发布了快5年了,迭代了30多个版本! 功能已经非常稳定了。
MySQL 8.0性能强劲,全内存访问可以轻易跑到200万QPS,I/O极端高负载场景跑到16万QPS。和MySQL 5.7 相比,benchmark性能提升明显:
(MySQL 8.0 Sysbench Benchmark: IO Bound Read Only)
(MySQL 8.0 Sysbench Benchmark: Read Write)
MySQL 8.0还有一些非常好的新功能,这里挑几个重要说一下:
1.默认字符集为 utf8mb4
多少年来我们使用 MySQL 都要在编码方面小心翼翼,生怕忘了将缺省的 latin 改掉而出现乱码问题,现在终于不用担心了,从 MySQL 8 开始,数据库的缺省编码将改为 utf8mb4,这个编码包含了所有 emoji 字符,对移动端应用非常友好。
2.优化器增强
MySQL8.0开始支持隐藏索引和降序索引,隐藏索引对性能调优非常有用,当一个索引被隐藏时,它不会被查询优化器所使用。
我们可以隐藏一个索引,然后看看数据库的性能,如果数据库性能没啥变化,说明索引是多余的,可以删除;如果性能下降,那证明这个索引是有用的,一定要保留(把它恢复显示即可)
降序索引允许优化器对多个列进行排序,并且允许排序顺序不一致。
3.更完善的JSON支持
扩展了JSON语法,提供了聚集函数,Merge函数,改善了排序性能,支持部分更新。
还新增了JSON_TABLE()函数,可以将JSON数据转换成表。
4.GIS的提升
MySQL 8.0 对 GIS(译者注:Geographic Information System 地理信息系统) 的支持有非常高的提升,功能上直追 PostgreSQL。
5.公共表表达式
MySQL 8.0新增了CTEs 功能(Common Table Expresssions)。这是一个命名的临时结果集,仅在单个 SQL 语句的执行范围内存在,可以是自引用,也可以在同一查询中多次引用。
6.窗口函数
窗口函数有点像是 SUM()、COUNT() 那样的集合函数,但它并不会将多行查询结果合并为一行,而是将结果放回多行当中,它可以极大地降低代码复杂性并帮助开发人员提高工作效率。
7.DDL原子化
DDL原子化是将与DDL操作相关的数据字典更新、存储引擎操作、二进制日志写入结合到一个单独的原子事务中,这使得即使服务器崩溃,事务也会提交或回滚。使用支持原子操作的存储引擎所创建的表,在执行DROP TABLE、CREATE TABLE、ALTER TABLE、 RENAME TABLE、TRUNCATE TABLE、CREATE TABLESPACE、DROP TABLESPACE等操作时,都支持原子操 作,即事务要么完全操作成功,要么失败后回滚
8.安全和账户管理
MySQL 8.0 开始支持“角色”的概念,角色是权限的集合,用户如果被赋予了某个角色,就会拥有相关的权限。
MySQL 8.0中的用户相关的系统表使用了支持事务的InnoDB引擎(之前是MyISAM),这样在对用户进行操作时,就不会出现部分用户成功,部分用户失败的情况。
MySQL 8.0把caching_sha2_password作为默认的身份验证插件而不是之前版本的mysql_native_password,提供了更高的安全性。
9.数据字典
在之前的MySQL版本中,字典数据都存储在元数据文件和非事务表中。从MySQL 8.0开始新增了事务数据字典,在这个字典里存储着数据库对象信息。
类似的新功能还有很多, MySQL 8.0不仅在性能上做了巨大提升,在功能上也更加完善,MySQL 8.0已经被国内外众多公司使用,最终是要大面积替代MySQL5.7的。如果你在用低版本的MySQL,建议升级到MySQL 8.0 ,对于新应用,直接上MySQL 8吧!