本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
MySQL数据库为适应如今高并发的场景,可以说做了诸多优化,其中,mysql的引擎,是有巨大改变的,今天的主题就是围绕着innodb这个引擎展开而讲的,高性能中的一小部分——引擎的缓冲区:bufferpool。常听说:MySQL数据库在较高配置的机器上每秒可以抗下几干的读写请求。 试想如果来一个请求就做一次以上的磁盘IO(随机IO),那是很难支撑高并发的。为了提速,根本上还是几个方面的问题:
- 1、内存取代磁盘;
- 2、随机IO变顺序IO。
而用内存把随机IO处理为顺序IO就是BufferPool的任务之一。
Innodb引擎SQL执行流程
举个例子说明:下面是一张存在磁盘上的表数据,这张表叫web
+----+--------------+---------------------------+-------+---------+
| id | name | url | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1 | Google | https://www.google.cm/ | 1 | USA |
| 2 | 淘宝 | https://www.taobao.com/ | 13 | CN |
| 3 | 菜鸟教程 | http://www.runoob.com/ | 4689 | CN |
| 4 | 微博 | http://weibo.com/ | 20 | CN |
| 5 | Facebook | https://www.facebook.com/ | 3 | USA |
+----+--------------+---------------------------+-------+---------+
我想把其中一条数据修改一下
UPDATE web SET alexa='5000', country='USA' WHERE name='菜鸟教程';
那么!这条语句在mysql的innodb执行引擎中到底是怎样发生的?
- 磁盘文件(数据存储的地方)上的数据以一个page页的单位被读到bufferpool(内存)中。
- bufferpool先写undo日志,例如:把 ID=3,name=菜鸟教程,url=xxxx ,Alexa=4689,country=CN 这条数据 写入undo日志
- 执行器修改bufferpool里的记录。例如:bufferpool里数据更新为【ID=3,name=菜鸟教程,url=xxxx ,Alexa=4689,country=USA】
- 执行器修改记录记入redo log buffer。例如:【ID=3,name=菜鸟教程,url=xxxx ,Alexa=4689,country=USA】记入redo log buffer。
- redo log buffer 生成文件进磁盘。例如:【ID=3,name=菜鸟教程,url=xxxx ,Alexa=4689,country=USA】由内存到磁盘
- 执行器写binlog日志文件。例如:【ID=3,name=菜鸟教程,url=xxxx ,Alexa=4689,country=USA】记入binlog文件,以备日后事务回滚或者出现意外时用于恢复数据的。
- commit事务,记commit进binlog日志redo日志文件。
- bufferpool里的记录记入磁盘文件。
总结
乍一看,这不是增添了很多麻烦?这会变快吗?这不是会拖后腿吗?
MySQL每次更新语句都是更新的Buffer Pool里的数据。(更新内存快于更新磁盘)
记binlog日志、redo日志、undo日志保证恢复或回滚数据,且数据具有一致性。(mysql除了保证你的数据读写性能,还要保证数据安全,这步不能少,就看怎么优化会让这一步又省时又能完成任务)
Buffer Pool会顺序写磁盘文件。(mysql在内存里折腾一番,不仅仅是贪图内存快这点点小便宜,而是,折腾出顺序,让内存到磁盘这趟路走得更省时省力!)