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

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

本文简单介绍下最新的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中才能看到怎么实现的了。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
存储 关系型数据库 MySQL
MySQL InnoDB数据存储结构
MySQL InnoDB数据存储结构
|
1月前
|
存储 缓存 关系型数据库
MySQL的varchar水真的太深了——InnoDB记录存储结构
varchar(M) 能存多少个字符,为什么提示最大16383?innodb怎么知道varchar真正有多长?记录为NULL,innodb如何处理?某个列数据占用的字节数非常多怎么办?影响每行实际可用空间的因素有哪些?本篇围绕innodb默认行格式dynamic来说说原理。
803 6
MySQL的varchar水真的太深了——InnoDB记录存储结构
|
2月前
|
安全 关系型数据库 MySQL
mysql安全性能
mysql安全性能
37 10
|
3月前
|
缓存 关系型数据库 MySQL
如何优化MySQL性能
对于使用MySQL数据库的开发人员来说,优化数据库性能是一个非常重要的任务。本文将介绍一些优化MySQL性能的方法,包括索引优化、查询优化、硬件升级等方面,帮助开发人员提高应用程序的性能和响应速度。
113 0
|
2月前
|
存储 缓存 关系型数据库
MySQL - 存储引擎MyISAM和Innodb
MySQL - 存储引擎MyISAM和Innodb
|
4天前
|
存储 关系型数据库 MySQL
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
13 0
|
12天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
12天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
2月前
|
关系型数据库 MySQL 数据库
RDS数据库测评:性能超出预期,双11优惠还在继续
RDS数据库测评:性能超出预期,双11优惠还在继续
30 0
|
2月前
|
存储 SQL 关系型数据库
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
72 0

相关产品

  • 云数据库 RDS MySQL 版