MySQL8.0.13: 几个和innodb性能相关的小改动

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介:

本文简单介绍下最新的Mysql8.0.13版本几个和性能相关的小改动

1. bug#84958

commit

问题描述:
当聚主要集索引记录上有多个版本时,从聚集索引上读取记录时的时间复杂度是0(N),但通过二级索引查询的时间复杂度可能为O(N^2)

解决思路:
代码是由facebook的工程师提供的补丁,主要思路是增加一个新的类Row_sel_get_clust_rec_for_mysql,其中cache了上次的clust record和老版本,可以在下次循环中重用。当发现定位到的clust rec和上次相同时,就无需遍历版本链,直接拿上次看到的版本,否则的话更新cach的记录

举个简单的例子,记录(1,2,3), pk = 1, sec index entry = (2,3);
记录更新为(1,2,4), 则sec index entry上记录为(2,3)(delete marked), (2,4), 均指向pk 1,那么在查询时可能需要去看对应的clust record.实际上看到的只有一个版本,那么在第二次找到(2,4),想去检查
记录可见性时,就可以直接使用上次拿到的版本,无需扫描版本链。

但这个实现也只是缓存上次的clust记录,这意味着如果在二级索引上扫描到的记录不是连续的,就可能用不上这个优化。

bug#91759

commit

主要改动:

在之前的版本中,innodb open一个read view,会先prepare(),在锁保护下拷贝全局事务id,然后在调用complete(), 去再更新ReadView的up_limit_id

complete可能在全局事务锁内或者锁外部执行。这实际上是没有什么必要的,complete()函数可以彻底移除掉,对应的代码转移到ReadView::prepare的执行路径中

官方测试在arm64场景下有一定的性能提升

undo truncate

commit

从commit log来看,官方应该有个更加全面完善的修复方案,但在下一个版本修复,在当前版本只是做了部分修复。

问题描述:
从MySQL5.7开始对独立的undo tablespace进行truncate操作,解决了之前被人诟病很久的undo膨胀问题,但在每次truncate undo tablespace时,执行真正文件操作之前和之后都需要做一次强制checkpoint。我们知道checkpoint在高负载场景下,带来的是极端page flush,高写入负载下,可能持续的影响到实例前端的吞吐量和相应时间。

那么为什么需要checkpoint呢? 个人理解是:

  • 当文件size缩小时,如果内存里还有脏页,可能在io时候无法写入抛错
  • 崩溃恢复时,无需去对已经truncate的page做日志应用

解决方案:

  • 在truncate文件之前,将对应undo tablespace的page从buffer pool驱逐掉
  • 在truncate文件之后,将涉及的dirty page flush到磁盘

既然不做checkpoint了,那么在崩溃恢复时,是否可能尝试去读取不存在的page做log application, 从而导致崩溃恢复失败呢? 个人觉得这里可能是存在bug的, 因为在崩溃恢复时并没有去检查page no是否在tablespace范围内,可能在fil_io时报invalid page accessing错误。已经report到官方,并被确认 bug#93170

SELECT COUNT(*)

目前社区已经有很多用户报select count(*)效率底下,其根本原因是从8.0开始,mysql默认使用clust index来计算总行数,其初衷是clust index上包含全部数据,没有二级索引的回表检查开销,而且只需要统计pk的个数即可。但这个优化方案忽略了二级索引可能比聚集索引更快:

  • 二级索引比聚集索引更小,因此产生的IO可能更小
  • 二级索引上记录并不总是需要回表

虽然8.0.13的release note写了select count() 被优化,但实际上这是个乌龙(只能说是回退吧...)。根据在slack上和innodb老大sunny的交流,真正的优化没有来得及合并进去,在release前三天被冻结住了。8.0.13只是实现了WL#10398,可以使用不同的索引来执行select count()。最终的官方的优化大体思路是通过在innodb并行scan btree来加速count(*),但恐怕我们只能在8.0.14中才能看到怎么实现的了。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
228 66
|
19天前
|
存储 缓存 关系型数据库
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
MySQL的存储引擎是其核心组件之一,负责数据的存储、索引和检索。不同的存储引擎具有不同的功能和特性,可以根据业务需求 选择合适的引擎。本文详细介绍了MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案。
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
|
24天前
|
存储 关系型数据库 MySQL
MySQL存储引擎详述:InnoDB为何胜出?
MySQL 是最流行的开源关系型数据库之一,其存储引擎设计是其高效灵活的关键。InnoDB 作为默认存储引擎,支持事务、行级锁和外键约束,适用于高并发读写和数据完整性要求高的场景;而 MyISAM 不支持事务,适合读密集且对事务要求不高的应用。根据不同需求选择合适的存储引擎至关重要,官方推荐大多数场景使用 InnoDB。
67 7
|
1月前
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
134 7
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
169 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
1月前
|
存储 关系型数据库 MySQL
MySQL引擎InnoDB和MyISAM的区别?
InnoDB是MySQL默认的事务型存储引擎,支持事务、行级锁、MVCC、在线热备份等特性,主索引为聚簇索引,适用于高并发、高可靠性的场景。MyISAM设计简单,支持压缩表、空间索引,但不支持事务和行级锁,适合读多写少、不要求事务的场景。
61 9
|
2月前
|
SQL 关系型数据库 MySQL
MySQL性能探究:count(*)与count(1)的性能对决
在MySQL数据库的性能优化中,对查询语句的细微差别有着深入的理解是非常重要的。`count(*)`和`count(1)`是两种常用的聚合函数,用于计算行数。在面试中,面试官经常会问到这两种函数的性能差异。本文将探讨`count(*)`与`count(1)`的性能对比,并整理十道经典的MySQL面试题,帮助你在面试中游刃有余。
106 3
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的段、区和页
MySQL的InnoDB存储引擎逻辑存储结构与Oracle相似,包括表空间、段、区和页。表空间由段和页组成,段包括数据段、索引段等。区是1MB的连续空间,页是16KB的最小物理存储单位。InnoDB是面向行的存储引擎,每个页最多可存放7992行记录。
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的表空间
InnoDB是MySQL默认的存储引擎,主要由存储结构、内存结构和线程结构组成。其存储结构分为逻辑和物理两部分,逻辑存储结构包括表空间、段、区和页。表空间是InnoDB逻辑结构的最高层,所有数据都存放在其中。默认情况下,InnoDB有一个共享表空间ibdata1,用于存放撤销信息、系统事务信息等。启用参数`innodb_file_per_table`后,每张表的数据可以单独存放在一个表空间内,但撤销信息等仍存放在共享表空间中。
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL的InnoDB存储引擎
InnoDB是MySQL的默认存储引擎,广泛应用于互联网公司。它支持事务、行级锁、外键和高效处理大量数据。InnoDB的主要特性包括解决不可重复读和幻读问题、高并发度、B+树索引等。其存储结构分为逻辑和物理两部分,内存结构类似Oracle的SGA和PGA,线程结构包括主线程、I/O线程和其他辅助线程。
【赵渝强老师】MySQL的InnoDB存储引擎

相关产品

  • 云数据库 RDS MySQL 版