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
相关文章
|
20天前
|
关系型数据库 MySQL
【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-01
【4月更文挑战第18天】MySQL的InnoDB引擎支持行锁,而MyISAM只支持表锁。行锁在事务开始时添加,事务结束时释放,遵循两阶段锁协议。为减少锁冲突影响并发,应将可能导致最大冲突的锁操作放在事务最后。例如,在电影票交易中,应将更新影院账户余额的操作安排在事务末尾,以缩短锁住关键行的时间,提高系统并发性能。
15 4
|
1天前
|
存储 算法 关系型数据库
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
|
3天前
|
运维 负载均衡 关系型数据库
MySQL高可用解决方案演进:从主从复制到InnoDB Cluster架构
MySQL高可用解决方案演进:从主从复制到InnoDB Cluster架构
|
3天前
|
存储 SQL 关系型数据库
MySQL的优化利器⭐️索引条件下推,千万数据下性能提升273%🚀
以小白的视角探究MySQL索引条件下推ICP的优化,其中包括server层与存储引擎层如何交互、索引、回表、ICP等内容
MySQL的优化利器⭐️索引条件下推,千万数据下性能提升273%🚀
|
4天前
|
存储 SQL 关系型数据库
mysql中MyISAM和InnoDB的区别是什么
mysql中MyISAM和InnoDB的区别是什么
11 0
|
4天前
|
存储 关系型数据库 MySQL
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
本篇文章来讨论MySQL字段的字符类型选择并深入实践char与varchar类型的区别以及在千万数据下的性能测试
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
|
9天前
|
存储 关系型数据库 MySQL
【MySQL系列笔记】InnoDB引擎-数据存储结构
InnoDB 存储引擎是MySQL的默认存储引擎,是事务安全的MySQL存储引擎。该存储引擎是第一个完整ACID事务的MySQL存储引擎,其特点是行锁设计、支持MVCC、支持外键、提供一致性非锁定读,同时被设计用来最有效地利用以及使用内存和 CPU。因此很有必要学习下InnoDB存储引擎,它的很多架构设计思路都可以应用到我们的应用系统设计中。
159 4
|
14天前
|
缓存 关系型数据库 MySQL
【专栏】提升MySQL性能和高可用性的策略,包括索引优化、查询优化和事务管理
【4月更文挑战第27天】本文探讨了提升MySQL性能和高可用性的策略,包括索引优化、查询优化和事务管理。通过合理使用B-Tree和哈希索引,避免过度索引,以及优化查询语句和利用查询缓存,可以改善性能。事务管理中,应减小事务大小并及时提交,以保持系统效率。主从或双主复制可增强高可用性。综合运用这些方法,并根据实际需求调整,是优化MySQL的关键。
|
14天前
|
存储 监控 关系型数据库
【MySQL】InnoDB 什么情况下会产生死锁
【MySQL】InnoDB 什么情况下会产生死锁
|
16天前
|
SQL 关系型数据库 MySQL

相关产品

  • 云数据库 RDS MySQL 版