mysql 性能优化——磁盘刷脏页性能优化

前言

大家是不是感觉mysql 更新挺快的呀,有没有想过mysql 更新为什么那么快。按道理说,mysql 更新都是先找到这一行数据,然后在去更新。意味着,就有两次磁盘操作,一个是磁盘读,一个是磁盘写。如果真的是这样的话,肯定会很慢呀,mysql 也没有那么傻。

当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log 里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面 。这个过程就是flush,flush 就是把内存里的数据写入到磁盘的过程。

当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。也可以这么说,内存的数据一定是最新的。那什么时候数据会flush呢。

数据库的flush

  1. redo log 已经写满了,每个更新操作,都会在 redo log 记录,这样当mysql 崩溃后,可以用redo log 恢复,这种能力就是crash-safe

  2. 就是系统内存不足。当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是“脏页”,就要先将脏页写到磁盘,这样就保证了数据页有两种状态。

    1)内存里存在,内存里肯定是正确的结果,直接返回

    2)另一种是内存里没有数据,就可以肯定数据文件上是正确的结果,读入内存后返回。这样的效率最高。

  3. mysql 业务操作不是很繁忙的时候

  4. mysql 正常关闭的时候

关于性能方面,4、3 两点都不会对mysql 性能没有什么影响。下面要着重讲解下1、2两点。 1点是redo log写满了,要flush 脏页,这种情况是要避免的,此时,整个系统就不在更新操作了,必须先刷脏页,只有redo log有空间了,才会继续更新。 第2点是内存不够用了,要先将脏页写到磁盘,这种情况是常态。InnoDB 用缓冲池(buffer pool)管理内存,缓冲池中的内存页有三种状态:1)还没有使用 2)使用了并且是干净页 3)使用了并且是脏页

为了提高系统的性能,Innodb 尽量会使用内存,因此对于一个长时间运行的库来说,未被使用的页面很少。当读入的数据页没有在内存的时候,必须到 buffer pool 申请一个数据页。如果没有数据页了,只能淘汰那些最久没有使用的数据页,淘汰的数据页如果是干净页,直接释放,如果是脏页,就必须把它刷到磁盘,变成干净也才能使用。那mysql 怎么知道是脏页呀,这个就是buffer pool脏页列表,最开始更新的就放在脏页列表,刷盘后,就从脏页列表移除。

刷脏页虽然是mysql 最终必须要做的事情,有些可能会影响mysql 性能

  1. 一个查询淘汰的脏页个数太多,这些脏页必须先merge 操作,会把脏页写到磁盘,会影响性能

  2. redo log 写满后,更新全部堵塞,必须先刷脏页,这种情况对更新频繁的业务来说不能接受的

针对这些情况,innodb 用了一些机制,避免这些情况的发生。

nnoDB 如何控制刷脏页的

根据上面所述,innodb 刷脏页的能力非常重要,能力弱,刷脏页就少,等业务繁忙,很快redo log 写满了,业务更新停摆了。整个能力其实就是配置的,可以看下图:

你要正确地告诉 InnoDB 所在主机的 IO 能力,这样 InnoDB 才能知道需要全力刷脏页的时候,可以刷多快。 这就要用到 innodb_io_capacity 这个参数了,它会告诉 InnoDB 你的磁盘能力。这个值我建议你设置成磁盘的 IOPS。磁盘的 IOPS 可以通过 fio 这个工具来测试,下面的语句是我用来测试磁盘随机读写的命令:

 fio -filename=$filename -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest 

我在测试环境是这样的:

bs=16k 一次读取页的大小,size=1G 写1G的数据,runtime 运行了60s,最终测试得 write IOPS = 37.2k = 37200。此时

innodb_io_capacity = 37200 ,这个就是刷盘能力,要考虑服务的负载,可以稍微低于这个值。

现在我们已经合理设置了刷脏页的能力,那么它的刷脏页的速度是怎么计算的呢?

InnoDB 的刷盘速度就是要参考这两个因素:一个是脏页比例,一个是 redo log 写盘速度。

那么速度具体是怎么计算的:

show global variables like 'innodb_max_dirty_pages_pct';
  1. 参数 innodb_max_dirty_pages_pct 是脏页比例上限,默认值是 90%。InnoDB 会根据当前的脏页比例(假设为 M),算出一个范围在 0 到 100 之间的数字,是F1(M)

  2. nnoDB 每次写入的日志都有一个序号,当前写入的序号跟 checkpoint 对应的序号之间的差值,我们假设为 N。InnoDB 会根据这个 N 算出一个范围在 0 到 100 之间的数字,这个计算公式可以记为 F2(N)。

  3. Max(F1(M),F2(N)) = R,

  4. innodb_io_capacity*R% = 刷盘数度

上面 F1(M)和F2(N)大家知道有这么回事就行,不必深究,想知道具体算法,只能看源码呢?只要设置合适的 innodb_io_capacity 就可以了。

平时我们要监控脏页的比率,不让接近 innodb_max_dirty_pages_pct 这个值,接近了就要报警,说明开始刷脏页,就会影响更新的性能。

select VARIABLE_VALUE into @a from global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty';
select VARIABLE_VALUE into @b from global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_total';
select @a/@b;

还有一个参数也需要关注:

show global variables like 'innodb_flush_neighbors';

值为1它旁边的脏页也会被刷到磁盘,会一直刷到不是脏页为止,是个连锁的反应。1 只会刷本来的脏页。

机械硬盘时代是很有意义的,可以减少很多随机 IO。机械硬盘的随机 IOPS 一般只有几百,相同的逻辑操作减少随机 IO 就意味着系统性能的大幅度提升。

使用的是 SSD 这类 IOPS 比较高的设备的话,我就建议你把 innodb_flush_neighbors 的值设置成 0。因为这时候 IOPS 往往不是瓶颈,而“只刷自己”,就能更快地执行完必要的刷脏页操作,减少 SQL 语句响应时间。

好了写到这里了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/445248.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用 SPL 高效实现 Flink SLS Connector 下推

作者:潘伟龙(豁朗) 背景 日志服务 SLS 是云原生观测与分析平台,为 Log、Metric、Trace 等数据提供大规模、低成本、实时的平台化服务,基于日志服务的便捷的数据接入能力,可以将系统日志、业务日志等接入 …

【鸿蒙开发】第十七章 Web组件(一)

1 Web概述 Web组件用于在应用程序中显示Web页面内容,为开发者提供页面加载、页面交互、页面调试等能力。 页面加载:Web组件提供基础的前端页面加载的能力,包括:加载网络页面、本地页面、html格式文本数据。 页面交互&#xff1a…

Python学习之基础语法

一、HelloWorld 二、Python基础语法 2.1 字面量 定义:在代码中,被写下来的固定的值,称之为字面量。 常用的6种值的类型 字符串 Python中,字符串需要用双引号包围; 被双引号包围的都是字符串 666 13.14 "黑马…

YOLOv3: An Incremental Improvement

新网络是YOLOv2、Darknet-19中使用的网络和那些新奇的残余网络之间的混合方法。我们的网络使用连续的3 3和1 1卷积层,但现在也有一些快捷连接,并且明显更大。它有53个卷积层,所以我们叫它Darknet-53。 这个新网络比Darknet19强大得多&#…

misc40

下载附件,发现只有第三个wav文件需要密码,其他都可以看 打开 conversion.txt 二进制转十进制得到202013 开 一张普通的二维码.png,直接扫不出结果。 010查看图片尾部发现 Brainfuck 编码 解码得到: 和谐民主和谐文明和谐和谐和谐…

WebStorm 开启 eslint 自动格式化配置

之后在 ctrl s保存之后,webstorm 都会根据eslint 的规则自动格式化。

缓存雪崩,穿透,击穿

为什么要设置缓存: 有海量并发的业务场景需要,大量的请求涌入关系型数据库,基于磁盘的IO读取效率低下,常用的mysql数据库不易进行扩展维护,容易造成数据库崩溃,从而相关业务崩溃,系统崩溃。 因此…

【C++初阶】第五站:C/C++内存管理 (匹配使用,干货到位)

前言: 本文知识点: 1. C/C内存分布2. C语言中动态内存管理方式3. C中动态内存管理4. operator new与operator delete函数 5. new和delete的实现原理 (干货在此) 6. 定位new表达式(placement-new)7. 常见面试题 目录 C/C内…

spring boot 学习

目录 引言: 一、Spring Boot概述 二、Spring Boot的核心特性 1 自动配置 2 起步依赖 3 内嵌容器 4 监控与管理 三、Spring Boot的入门步骤 1 环境安装 2 创建项建 3 编写代码 1 启动类 2 控制器 3服务 4自动装配 5配置属性 6 JPA实体 4 运行与调试…

Linux网络套接字之UDP网络程序

(。・∀・)ノ゙嗨!你好这里是ky233的主页:这里是ky233的主页,欢迎光临~https://blog.csdn.net/ky233?typeblog 点个关注不迷路⌯▾⌯ 实现一个简单的对话发消息的功能! 目录…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:RotationGesture)

用于触发旋转手势事件,触发旋转手势的最少手指为2指,最大为5指,最小改变度数为1度。 说明: 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 接口 RotationGesture(value?: …

Oracle SQL优化(读懂执行计划 一)

目录 SQL执行计划的作用示例演示执行计划概念介绍执行计划实例DISPLAY_CURSOR 类型DISPLAY_AWR 类型 指标详解 SQL执行计划的作用 示例演示 执行计划概念介绍 执行计划实例 DISPLAY_CURSOR 类型 DISPLAY_AWR 类型 指标详解

C/C++指针详解

接下来我们来介绍一下什么是指针? 指针其实就是元素存放地址,更加形象的比喻:在酒店中如果你想要去注必须去付费不然不能住,在计算机也同样如此(但是不需要付费哦)每当我们使用一个变量或其他需要申请空间…

三、N元语法(N-gram)

为了弥补 One-Hot 独热编码的维度灾难和语义鸿沟以及 BOW 词袋模型丢失词序信息和稀疏性这些缺陷,将词表示成一个低维的实数向量,且相似的词的向量表示是相近的,可以用向量之间的距离来衡量相似度。 N-gram 统计语言模型是用来计算句子概率的…

数据结构(二)——线性表(双链表)

2.3.3 双链表 单链表:单链表结点中只有一个指向其后继的指针,使得单链表只能从前往后依次遍历,无法逆向检索,有时候不太方便 双链表的定义:双链表结点中有两个指针prior和next,分别指向其直接前驱和直接后继 表头结点…

Jmeter---非GUI命令行的执行生成报告、使用ant插件执行接口测试脚本生成报告

非GUI命令行的执行 1. 在jmx后缀的文件目录下打开命令行 2. 运行: jmeter -n -t filename.jmx(-n : 非GUI的方式 -t: 指定需要执行的脚本) 生成jtl报告 运行: jmeter -n -t filename.jmx -l result_filename.jtl 生成html报…

C语言笔记:文件的操作各种文件函数讲解

突然发现自己的C语言文件部分还没有学,赶紧来补一下~~ 1.文件分类 文本文件磁盘文件(二进制文件)C语言特殊文件标识:stdin(标准输入:通指键盘输入),stdout(标准输出&am…

基于SpringBoot的招聘网站

基于jspmysqlSpring的SpringBoot招聘网站项目(完整源码sql) 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》…

网络编程总结

文章目录 1.浏览器输入一个 url 中间经历的过程2.TCP,UDP 的区别3.HTTP 协议HTTP 协议有哪些部分组成?响应状态码GET 和 POST 的区别什么是幂等的什么是 HTTP 的长链接cookie 和 session 的区别TCP socket 编程原理 4.IO 多路复用五种 IO 模型如何提升服务器的并发能…

Ubuntu 基本操作-嵌入式 Linux 入门

在 Ubuntu 基本操作 里面基本就分为两部分: 安装 VMware 运行 Ubuntu熟悉 Ubuntu 的各种操作、命令 如果你对 Ubuntu 比较熟悉的话,安装完 VMware 运行 Ubuntu 之后就可以来学习下一章节了。 1. 安装 VMware 运行 Ubuntu 我们首先来看看怎么去安装 V…