mysql InnoDB内存加载、管理机制、执行流程

1. 内存缓存结构(BufferPool)

如果电脑只部署了mysql服务的话,可以把80%的内存给它使用。默认情况下,BufferPool默认是128M,可以更改。

2. 内存与磁盘数据交互机制

有了内存后,怎么与磁盘交互呢,交互就是我的内存怎么从磁盘中拿数据,内存改了后怎么同步到磁盘,这必须有个交互的单位。最小的交互单位是page页。

预读机制:就是提前一步帮你拿到一些页面数据放在内存里,下一次读的时候,就可以之间去内存里读了。预读有两种方式,一个是线性预读,一个是随机预读。

线性预读:但我读取一个页的数据时,我会将同一个区的数据加载到内存里,到底是多少个页访问,这里也是可以配置的,默认是56,你可以配置0-64。

随机预读:不管你的顺序,只要我的区里有连续的13页被访问,那么我会把这个区内相同的数据放在这个内存里面。

3. BufferPool内存管理

内存管理,就是当我的数据满了以后该怎么办,innodb里面主要用的是淘汰。

LRU:根据时间来,后面没有访问的就淘汰,谁越久没有访问谁就越容易被淘汰。

列表+hash,列表表示我保存的数据,hash就是找到它的位置

由于innodb的预加载机制,普通的LRU会存在很大问题,就是是没有用到的page被预加载到内存里面,导致删除了那些有用的page,对此innoDB采用了LRU的变种处理。

LRU变种:

  1. 当页面访问的时候,不管是预加载的还是正在用的,也就是放在bufferPool里的page数据,放在中间,也就是oldList的头
  2. 但old的数据被访问的时候,我才放到newlsit的头
  3. 随着newList的数据添加,数据往后移,淘汰old的底部tail

4. InnoDB内存与磁盘同步机制

如果每一次操作都和磁盘进行同步的话,性能会变得非常非常慢,所以在InnoDB,采取的是异步刷盘的机制,就是优先改动内存的数据,然后异步保存在磁盘,但是这一定会出现数据不一致的页,这种页也叫做脏页。这要考虑线程数、触发机制

线程数:innodb_page_cleaners:这个是表示几个线程去刷脏。默认值是4,虽然默认是4,但是不能超过innodb bufferpool的实例数

触发机制:

  • 脏页自适应:就是当我内存里面的脏页达到一定的比例或者说一定的数量时,我就会去刷新。
  • RedoLog自适应:会根据Redolog页的生成速度来自适应
  • 空闲时间刷新:但我的线程空闲的时候就会去刷新

doubleWrite

为了解决在异步保存的时候有一个page出错,导致同步出错,对此提出一个双写机制,就是添加一个备份,防止出现这种情况。在8.0.2版本之后,就有一个独立的 doubleWrite 文件。你需要备份,那么就需要有一个地址,备份到底在哪里,备份多少份。所以第一个很重要的配置,就是我需要去备份多少份,默认是备份2份。还有备份的地址,如果这两份都没有配地址,那么就是在datadir下面。

changebuffer:

更改数据都是异步同步到磁盘的,但是在更改之前还是得从磁盘拿取,那么可不可以再优化,我先改了放到内存,然后下次读取相关数据后再合并。

在innodb里,changebuffer只针对二级索引的页,changebuffer一定改动的是页,但是一般我们不会去用,因为changebuffer只适合在一些操作的场景下使用,但不适合读多的场景。

4.1. RedoLog

RedoLong又叫做重做日志,当发生异常的时候,导致数据丢失,可以到RedoLog里面找到我想要的数据。因为innodb的操作只会实时地操作我们bufferpool里面的page页,然后通过一些其他的异步方式,将数据存入磁盘,数据丢失时很容易产生的。

redoLog的格式:

type代表这次操作的类型,插入修改还是删除

spaceId表示这次操作的是哪个表空间

page number 表示这次操作的是哪个页

data 表示这次操作的 修改前后的数据

redoLog是用于做数据恢复的,如果数据已经到磁盘,那么这些日记也就没有用了,所以我可以去覆盖原来的一些数据。redoLog设置的是循环写,如果这32个日志文件写满了,我会把之前的给覆盖掉,原来那些无用的数据也就删除了。redoLog只是一条日志,它的大小要比page小很多。

5. InnoDB执行流程总结

当客户端与连接层建立连接,然后发起一个sql语句的时候,服务层会经过以下几个点,首先经过解析器,解析器就是要知道客户端发送的sql语句是否正确,它分为词法解析和语法解析,经过语法解析后就进行预处理,预处理有两个作用,第一个就是减少了解析器的解析次数,第二个是防止sql注入。执行完成后,就到了优化器,优化器就是我去选择我的执行方案,要不要去走索引,怎么走索引,有了一个最佳方案后,就会去执行,所以会走到执行器,执行器就是去调用我们存储引擎的api,存储引擎又分为很多,主要有innodb、myisam、memory。但是默认是使用innodb,并且innodb保证了数据不会丢失。innodb为了性能,又分为两块,内存与磁盘。在磁盘里面,它有很多的数据结构,最外面的是表空间,表空间又分为独立表空间、系统表空间、共享表空间,表空间里面就是有段,段又分为数据段和索引段,数据段->区->页->行,为什么要有怎么多层级,主要是为了更好的去管理这些数据。

改数据的时候,首先内存里面肯定没有,从磁盘加载数据,最小的单位是页,在内存里面会提前预分配好页,如果没有加载数据的页叫做空页,如果数据改动了那么叫脏页,如果加载出来没有改动叫做干净的页。如果更改数据的时候,在内存里改了,但是在磁盘里没有改,那么这个页叫脏页,脏页我们必须要同步到磁盘,这个同步是异步的,这个过程也叫做刷脏。既然是异步刷脏的,就会存在数据不一致问题。为了在内存异步同步磁盘的过程中,数据库宕机导致的数据丢失,所以在commit提交的时候,我一定会记录到我的redoLog的磁盘里,一定会去写一份redolog,redolog是记录的是在哪一个页,哪一个表空间做了哪些改动,也叫做物理日志,它比page页直接同步到磁盘有两个优势,比page的数据量要小,redolog是一个顺序io,因为redolog是一个一个追加的,而page页改动的是不知道在磁盘哪个位置的。还有一个logBuffer,就是修改的redolog放在logbuffer里,如果不需要实时同步的话,可以等待logbuffer往里面装几个redolog后再同步磁盘。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值