MySQL 笔记整理(12) --为什么我的MySQL会“抖”一下?
笔记记录自林晓斌(丁奇)老师的《MySQL实战45讲》
(本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除)
12) --为什么我的MySQL会“抖”一下?
断更了一段时间,因为这几周实在是太忙了,周末加班两天那种。。。
有时你会遇到这样的问题,一条SQL语句,正常执行的时候很快,但是有时候会变得特别慢。并且这种场景很难复现,不只随机而且持续时间很短。这其实与MySQL的脏页以及它的刷新机制有关。之前我们有过一个关于《孔乙己》里面酒馆老板记账的比喻。在这个比喻里,掌柜的账本就是我们的数据文件,掌柜的临时写下的粉板就是我们的日志文件(redo log),而掌柜的记忆就相当于我们的内存。
粉板可以记录的内容有限(redo log循环写),掌柜的记忆也是有限的,因此他总要找时间把这两部分的内容记录到账本里去。这个术语就是flush.
当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。
大致上有四种情景来进行刷“脏页”:
- 粉板满了。(redo log写满),redo log写满以后,如果又有了新的数据,就不得不去除一些之前的数据。当然,在去除之前,要先把正确的数据记录下来才行。
- 生意太好,短时间内有很多客人,掌柜的记不下来了。(系统内存不足)。内存不足时,需要先淘汰掉一些数据页,如果这些数据页中有“脏页”就必须要把这些记录到磁盘才行。你可能会有疑问,为什么不直接淘汰掉这些页呢,如果再有相关的记录,就利用redo log来还原数据呢?(掌柜的疑问一部分脑子里的记忆,下次再有的话,先看账本,然后再看粉板,倒退出最新的记录),这其实是从性能方面考虑的。如果我们保证每次刷脏页一定会写磁盘,那么下次再读的时候就有两种情况。一是内存中有记录,那么直接返回。二是,内存中没有,那么先从磁盘读,读到了就直接返回。对应掌柜的就是,掌柜的有印象,直接返回。掌柜的没有印象查看账本,找到了就直接返回。
- 生意不太忙的时候,掌柜的闲着没事,就更新账本。(系统空闲),闲着没事,Mysql就自己刷脏页玩。
- 年底放假,酒店关门几天。(MySQL正常关闭),正常关闭时MySQL会把内存的脏页都flush到磁盘上。
回到我们开始的问题,什么情况会抖一下呢?首先排除后两种,空闲或是要关闭数据库时。来看看前两种情况:
先是redo log写满了,要flush脏页,这种情况是InnoDB要尽量避免的。因为这种情况下,整个系统就不能再接受更新了,所有的更新都必须堵住。如果你从监控上看,这时的更新数会跌为0.然后是第二种情况:“内存不够用了,要先将脏页写到磁盘”。这种情况是常态。InnoDB用缓冲池(buffer pool)管理内存,缓冲池中的内存页有三种状态:
- 还没使用的
- 使用了并且是干净页的
- 使用了并且是脏页的
InnoDB的策略是尽量使用内存,因此对于一个长时间运行的库来说,未被使用的页面很少。当要读入的数据页没有在内存的时候,就必须到缓冲池中申请一个数据页。这时候只能把最久不使用的数据页从内存中淘汰掉。如果淘汰掉的是一个干净页,可以直接释放出来复用。如果淘汰掉的是一个脏页,就必须先将脏页刷到磁盘,变成干净页后才能复用。所以,刷脏页虽然是常态,但是出现以下两种情况,都会明显的影响性能:
- 一个查询要淘汰的脏页太多,会导致查询的响应时间明显变长
- 日志写满,更新全部堵住,写性能跌为0,这个情况对敏感业务来说,是不能接受的。
所以,InnoDB需要有控制脏页比例的机制,来尽量避免上面的这两种情况。
InnoDB刷脏页的控制策略:
首先,你要正确地告诉InnoDB所在主机的IO能力,这样InnoDB才能知道需要全力刷脏页的时候,可以刷多快。这个就要用到innodb_io_capacity这个参数了,它会告诉InnoDB你的磁盘能力。这个值建议你设置为磁盘的IOPS,磁盘的IOPS可以通过fio(linux)来进行测试。(Linux下fio,window下可以使用iometer)
InnoDB使用两个因素来进行计算刷盘速度。一个是脏页比例,一个是redo log的写盘速度。参数innodb_max_dirty_pages_pct是脏页比例上限,默认值是75%。InnoDB会根据当前的脏页比例M,算出一个范围在0到100之间的数字。InnoDB每次写入日志都有一个序号,当前写入的序号跟checkpoint对应的序号之间的差值,我们假设为N,同样,InnoDB会根据这个N算出一个0到100之间的数字。N越大这个计算出来的值就越大。然后,根据上述两个计算出的数据f(M)和f(N),取其中较大的值记为R,之后引擎就可以按照innodb_io_capacity定义的能力乘以R%来控制刷脏页的速度了。
因此要合理的设置innodb_io_capacity的值,平时要多关注脏页的比例,不要让它经常接近75%。
还有一个有趣的策略:一旦一个请求涉及到刷脏页,在准备进行刷脏页的时候,会把这个数据页旁边的数据页也检查一下,如果这个邻居也是脏页,那么就会把邻居一起刷掉。InnoDB使用参数innodb_flush_neighbors参数来控制这个行为,为1的时候就会触发这个“连坐”机制。在MySQL8.0中,这个默认值已经是0了。
上期问题:
如果你要维护学生信息的数据库,学生登录名统一是"学号@gamail.com",学号的规则是十五位的数字,前三位是城市编号,四到六位是学校编号,七到十位是入学年份,最后五位是顺序编号,只考虑登录验证的话,你会怎么设计这个登录名的索引呢?
由于这个学号的规则,无论是正向还是反向的前缀索引,重复度都很高。前三位是城市编号,四到六位是学校编号,这六位数字其实是相对固定的。而邮箱后缀也是确定的,因此可以只存入学年份加顺序编号,它们的长度是9位。在此基础上,可以用数字类型来存储这个9位数字,这样只需占用4个字节,这其实是一种hash,只是用了最简单的转换规则。
另有别的思路是,一个学校总人数不会很大,这点数据量,这个表必然是个小表。直接存原来的字符串,可以使业务更简单。这也是一种很好的回答,结合实际业务。
问题:
一个内存配置为128GB,innodb_io_capacity设置为20000的大规格实例,正常会建议你将redo log设置成4个1GB的文件,但是如果你配置时不小心将redo log设置为了4个100M的文件,会发生什么情况呢?为什么呢?
MySQL 笔记整理(12) --为什么我的MySQL会“抖”一下?的更多相关文章
- 最全mysql笔记整理
mysql笔记整理 作者:python技术人 博客:https://www.cnblogs.com/lpdeboke Windows服务 -- 启动MySQL net start mysql -- 创 ...
- MySQL 笔记整理(1) --基础架构,一条SQL查询语句如何执行
最近在学习林晓斌(丁奇)老师的<MySQL实战45讲>,受益匪浅,做一些笔记整理一下,帮助学习.如果有小伙伴感兴趣的话推荐原版课程,很不错. 1) --基础架构,一条SQL查询语句如何执行 ...
- MySQL笔记(七)远程连接MySQL
mysql 默认只允许 localhost 连接,因此在远程连接服务器上的 mysql 之前,需要做一些设置.在没有设置前,默认是下面的状况,mysql 只能由 localhost(127.0.0.1 ...
- MySQL 笔记整理(16) --“order by”是怎么工作的?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 16) --“order by”是怎么工作的? 在林老师的课程中,第15 ...
- MySQL 笔记整理(19) --为什么我只查一行的语句,也执行这么慢?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 19) --为什么我只查一行的语句,也执行这么慢? 需要说明一下,如果M ...
- MySQL 笔记整理(18) --为什么这些SQL语句逻辑相同,性能却差异巨大?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 18) --为什么这些SQL语句逻辑相同,性能却差异巨大? 本篇我们以三 ...
- MySQL 笔记整理(17) --如何正确地显示随机消息?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 17) --如何正确地显示随机消息? 如果有这么一个英语单词表,需要每次 ...
- MySQL 笔记整理(14) --count(*)这么慢,我该怎么办?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 14) --count(*)这么慢,我该怎么办? 有时你会发现,随着系统 ...
- MySQL 笔记整理(13) --为什么数据表删掉一半,表文件大小不变?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 13) --为什么数据表删掉一半,表文件大小不变? 我们还是以MySQL ...
随机推荐
- 用Service+Broadcast解决倒计时过程中Activity被销毁的问题
主要思想是这样的:将倒计时CountDownTimer放在Service里面进行,每过一秒就一条发广播,在主Activity里注册广播,收到广播后更新UI. 一.写一个类CodeTimerServic ...
- 部署Chart应用并使用.net core读取Kubernetes中的configMap
上一篇文章讲了 k8s使用helm打包chart并上传到腾讯云TencentHub,今天就讲一下使用Helm部署应用并使用configMap代替asp.net core 中的appsettings.j ...
- javascript模块化编程 从入门到实战
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...
- Bagging之随机森林
随机森林(Random Forest)是一种Bagging(Bootstrap Aggregating)集成算法,在样本随机(样本扰动)的基础上,进一步运用特征随机(属性扰动)的机制,得到比一般的Ba ...
- .NET Core IdentityServer4实战-开篇介绍与规划
一.开篇寄语 由于假期的无聊,我决定了一个非常有挑战性的活动,也就是在年假给大家带来一个基于OAuth 2.0的身份授权框架,它就是 IdentityServer4 ,如果没有意外的话,一定可以顺利的 ...
- Shim 与 Polyfill
Shim: 用来向后兼容.比如 requestIdleCallback,为了在旧的环境中不报错,可以加 shim. 使用环境中现有的 api 来实现,不会引入额外的依赖或其他技术. Polyfill: ...
- docker常规操作——启动、停止、重启容器实例
一.启动一个已经停止的容器实例 docker start 容器ID或容器名,建议使用容器ID,容器ID支持模糊查询而容器名称不支持1. 先查看已经暂停的容器实例信息 2. 通过docker start ...
- PHP开发模式之-单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Db{ private function __construct(){} private static ...
- 【推荐】桌面版AI伴侣 含2.47 2.49 2.51汉化版
桌面版AI伴侣,无需安装aiStarter,直接运行bat就能在电脑上启动AI伴侣,启动速度比虚拟机快很多.缺点是对硬件的要求比较高. 文件来自 https://mp.weixin.qq.com/s/ ...
- Sql Server 本地(客户端)连接服务器端操作
网有很多相关内容,我在此做记录和总结 1.主要是sql server 配置管理工具的配置 在此参考 https://www.cnblogs.com/yougmi/p/4616273.html(再次感谢 ...