暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MYSQL InnoDB 预读

224

目前,IO 仍然是数据库的性能杀手,为了提高 IO 利用率和吞吐量,不同的数据库都设计了不同的方法,本文就介绍下 InnoDB 提供的预读(read-ahead)功能,以及 Oracle 提供的多块读(multiblock-read)功能,并进行一些对比。

InnoDB read-ahead

InnoDB 提供了两种预读的方式,一种是 Linear read ahead,由参数innodb_read_ahead_threshold控制,当你连续读取一个 extent 的 threshold 个 page 的时候,会触发下一个 extent 64个page的预读。另外一种是Random read-ahead,由参数innodb_random_read_ahead控制,当你连续读取设定的数量的page后,会触发读取这个extent的剩余page。

InnoDB 的预读功能是使用后台线程异步完成的。InnoDB启动了innodb_read_io_threads个后台线程,来完成IO request,并且可以使用Native AIO,在你的环境中如果安装了libaio,在MySQL实例启动的时候,查看系统日志:InnoDB: Using Linux native AIO 表明 InnoDB 已经使用Native AIO了。在Linear read ahead触发的时候,InnoDB通过io_submit()提交了下一个extent的64个pages的IO request,并由一个read IO thread完成。

Oracle multiblock-read

当你要对堆表进行全表扫描,并需要大量IO的时候,通常在 session 级别设置db_file_multiblock_read_count,这样 Oracle 会在读取堆表结构的数据块的时候,一次IO读取多个数据块,大大减少了IO的次数。但这里一次合并IO请求的数据块,必须不能在buffer pool中,否则会分割IO请求。不过,在针对大表的汇总分析查找中,设置db_file_multiblock_read_count的效果是非常明显的。不过也要注意,不要在系统级别上设置过大的db_file_multiblock_read_count, 会造成buffer cache flooding。

场景分析


下面我们看两个非常典型的场景:

1. 高并发,小IO的情况 在高并发的场景下,sql响应时间主要取决于同步IO请求的时间,而InnoDB的预读通常不会触发,就算触发,更多的是预热(warmup)的效果,并不会对系统带来非常大的收益,对rt的影响也非常小。而Oracle如果设置了db_file_multiblock_read_count,在这样的场景下,有可能会适得其反,因为一次同步IO请求的时间增加了。

所以在这样的场景下,InnoDB的read-ahead和Oracle的multiblock-read并不会带来太多的收益。我们看另外一个场景。

2. 低并发,高IO吞吐 通常,我们可能想在业务低峰期,对线上数据进行汇总查询。这时,希望能够完全使用主机的资源来完成sql的查询,在使用全表扫描的时候,InnoDB会触发read-ahead,每次提前异步读取下一个extent的page,加快读取的速度。Oracle使用db_file_multiblock_read_count,一次IO读取多个block,提高读取的吞吐量。


问题

为什么在聚集查询的时候,Oracle的效果会比InnoDB要好?

这个问题,在针对机械盘的情况,又回到了 IOPS 和 throughput 的讨论上去了。InnoDB的read-ahead,在触发的时候,针对下一个extent,对每一个page提交了异步IO请求,也就是增加了IO request次数,虽然Native AIO和disk会有针对性合并IO,但仍然非常有限,而Oracle每次提交合并多个连续数据块的IO请求,能够更好利用disk的吞吐能力。

所以,InnoDB在针对aggregation类型的查询的时候,想要完全使用IO的吞吐能力,相比较Oracle的multiblock-read,会偏弱一点。

优化方法

针对InnoDB的机制,我们可以尝试几种优化方法:

  1. 在session级别,提供可设置预读的触发条件,并使用多个后台线程来完成异步IO请求。因为没有减少小IO请求,作者尝试了这种方法,收益甚小;

  2. 独立一个buffer pool,专门进行多块读,针对next extent,一次读取到buffer pool中,这种方式就和Oracle的multiblock-read比较类似了;

  3. 终极优化方法,就是使用并行查询,Oracle在全表扫描的时候,使用/* parallel */ hint方法启动多个进程完成查询,InnoDB的聚簇索引结构,需要逻辑分片,针对每一个分片启动一个线程完成查询。



安装

MYSQL二进安装

MYSQL8.0 二进制安装

MYSQL8024二进制安装脚本

Percona8.0 通用二进安装

Percona 8低版号升级


原理

MySQL Truncate undo  表空间

MYSQL两段提交BINGLOG REDOLOG关系

MYSQL双写和块裂

MySQL 可以添加多少 text字段?

MYSQL 热数据备份--Warmup特性

MySQL 线程池

MySQL InnoDB 事务锁源码分析

MYSQL SHUTDOWN 过程认识

InnoDB buffer pool flush策略



备份和恢复

MYSQL备份

MYSQL的恢复

使用MYSQLBINLOG工具恢复数据GTID范围

MYSQL 8 加密和流失备份

MYSQL 增量恢复

Mysql 物理备份Xtrabackup

MYSQL xtrabackup 全量压缩备份

MYSQL xtrabackup 增量备份

MYSQL 8 物理全量恢复2


主从复制

重建MYSQL主从库

MYSQL 最大可用模式

MYSQL ACTIVE DG 配置

MYSQL BINLOG 二进制日志

mysql反向同步

MYSQL从库的并发恢复

MYSQL延迟并发复制

MYSQL的只读GTID复制

MYSQL从库应用缓慢

Percona8.0 主从

MYSQL主从重要参数原理

MYSQL 主从复制数据不一致的风险



运维优化

理解MYSQL组提交和二阶段提交

MySQL两地三中心方案初步设计

MYSQL微服务架构

MYSQL-PTONLINE 改分区表

MYSQL经典PID问题



SQL优化

MYSQL5.7优化了WHERE条件前后顺序

基于案例理解MySQL执行计划

MYSQL 单表千万变慢

MYSQL也有HINT

500万的单表性能

MYSQL排序ORDER BY

mysql大量的waiting for table level lock怎么办

MYSQL METALOCK

MYSQL 死锁

MySQL的性能相关的视图

MYSQL SQL巡检脚本

MYSQL MEMCACHE插件

MYSQL优化思路

MYSQL LEFT JOIN 优化

MYSQL 加字段优化

MYSQL 字符集优化

MYSQL ID 的混乱星海

using filesort VS using temporary

MYSQL REDO   内参

MYSQL UNDO内参



MYSQL开发

MYSQL 常用函数

MYSQL 批量生成触发器

如何优雅更新MYSQL大表?


MYSQL分区维护

分区表

Mysql5.7范围分区操作

MYSQL普通表 在线 改成 分区表

MYSQL为什么分区要加入主键和唯一索引?

MYSQL在线分区之表锁


MGR集群

MYSQL MGR 集群

MYSQL MGR 从入门到精通01

MYSQL MGR 从入门到精通 02

MYSQL MGR  从入门到精通03

MGR重启

dba+开源工具:MySQL 8.0 MGR高可用VIP切换脚本



源码阅读

MYSQL 源码DEBUG编译

Mysql 2038 的BUG

MYSQL DEBUG 版本的发布




压测试工具

SYSBENCH


MYSQL 安全

MYSQL-SSL配置





文章转载自海鲨数据库架构师,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论