Posts 数据库学习bufferpool相关
Post
Cancel

数据库学习bufferpool相关

BufferPool

(1)空间管理:当执行一条 sql语句时,在定位到一个页后,会把页复制到buffer pool里。一个页在放入buffer pool时,由于buffer pool里的空间可能不是连续的,innodb是这样处理的。维持一个free链表,每个节点都指向一个空白页,取第一个节点。同样的,当buffer pool里出现新的空闲时,会再添加到free链表的尾部。

(2)脏页管理:维护一个flush链表,和free的思路类似。具体的update实现利用redo log实现

(3)页面淘汰算法:LRU链表实现。不过这种普通的应用淘汰算法存在一个困境,假设进行了一次全表扫描,会出现不停取页放进buffer pool从而导致其被全部换掉,这样一些本该是经常使用的热点数据就被换出去了,会降低性能。对此innodb进行了分区,将LRU链表切为5:3的冷热数据区,优先将冷数据区域作为普通的LRU使用,但是冷数据区如果有数据区在超过某个时间限制(比如1s)之后再次访问,就加入热数据区。相当于使用了两个普通的LRU。至于为什么要有时间限制,因为全表扫描时一页上不止一个数据,全表扫描会短时间内再次访问多次,用限制来回避了之前提出的困境

事务

(1)update的过程:先把数据放入bufferpool(内存),然后修改,然后生成redo log,持久化redo log(顺序IO,追加到文件后,默认在事务提交时持久化),bin log持久化,undo log,修改成功。以innodb默认为例,一开始会生成两个48Mlogfile,如果两个都满了,因为是循环使用的,这时候就会覆盖之前的redo log,会触发检查点。 这是会把log file里所有对应的页持久化到磁盘。(此处可以通过增大log file进行优化,增加工作效率,但是会增加重启时的耗时)

(2)redo log持久化的三种选择:innodb允许三个配置值:

  • 0:事务提交时不立刻持久化,任务交给后台线程做

  • 1:默认情况

  • 2:事务提交时,立即将redo log写入os的缓冲区,不直接持久化。这种情况数据库挂了而系统没挂的话事务的持久性还是保证了。但是万一一系统挂了就会丢失。

(3)bin log:注意,redo log为innodb独有,bin log是mysql的。bin log记录的是sql 语句,而redo log记录的是数据的修改。因此使用redo log显然会比bin log快。

This post is licensed under CC BY 4.0 by the author.

mysql索引学习

explain的参数解析