MySQL学习笔记(一)InnoDB内存数据结构浅析

以下文章来源于腾讯云数据库,作者陈俊熹

Innodb存储引擎是目前MySQL最主流的存储引擎,学习Innodb, 可以先从其最基础的数据结构开始。Innodb的数据结构主要包括内存数据结构(In-MemoryStructures),如buffer pool, change buffer, log buffer等, 磁盘数据结构(On-DiskStructures),如索引Index, 表空间及日志结构等。

Buffer Pool

Buffer Pool主要是对Innodb存储引擎中的数据表(Table)和索引数据(Index)的一个缓存,它使得MySQL可以直接对一些热数据在内存中进行读取。Innodb BufferPool的作用和操作系统中的Page Cache类似,作为缓存子系统,它们在设计和实现上有很多类似的地方。比如,Buffer Pool也使用page作为管理数据页的最小基本单元,同时使用链表来管理内存页,并且页框的淘汰回收算法都使用了LRU。不同的地方在于,Linux的页框回收算法中使用inactive和active两个链表来管理数据页pages,而在Innodb中,所有的数据页pages都在一个链表上,它通过一个中间点(MidPoint)指针将链表分为“new”和“old”两个子链表。


image

如上图所示,当数据页第一次被访问读入内存时,它被插入到MidPoint的位置,也就是“old”子链表的头部。通常来说,数据页被读入内存可能是因为一个query操作,或者是Innodb的预读操作。一个数据页如果是因为query操作被读入内存的,则它会被移动到整个链表的头部。有的数据页是被预读进来的,它不一定会立即被访问,此时它会一直存在于“old”链表内,直到它被淘汰。基于LRU的淘汰策略都存在一个瞬时访问命中率下降的问题。例如,MySQL在进行全表扫描时,会将大量的数据页读入内存,这些数据页几乎都不会再被上层查询所使用,因此又会快速的成为“old” pages被淘汰出内存。所以全表扫描的开销非常大,并且会污染Buffer Pool中的热数据。Innodb提供了一些设置来缓解这种情况。

首先,你可以通过设置参数“innodb_old_blocks_pct”来控制LRU链表中“old” pages的比例,其默认值是37,即有3/8的内存数据页会作为淘汰算法的候选页。“innodb_old_blocks_pct”的可设置范围为[5, 95],将该参数设成一个较小值,可以减轻全表扫描对内存热数据的影响,此时Buffer Pool中只有很少一部分空间会进行淘汰,而真正的热数据会被一直保留。另外一个参数“innodb_old_blocks_time”设置了一个时间窗,来规定一个数据页被插入到MidPoint之后,在多少时间后可以被移动到“new”子链表头部。

例如,将“innodb_old_blocks_time”值设置为1000ms(即1s),那么一个数据页被读入内存后,它在1s内无论被访问多少次,也不会成为热数据页。这个参数值可以缓解全表扫描引入的缓存污染问题。比如像全表扫描或预读load进内存的数据页,它们在很短一段时间内被访问后就不会再被访问了,那么此时他们仍然在“old”链表中,可以更快速的被淘汰出内存。

Change Buffer

Change Buffer使用了Buffer Pool的一部分空间,它主要对部分不在Buffer Pool中的数据页的写操作(包括插入,更新和删除)进行缓存。通常来说,Innodb所更新的一个数据页不在Buffer Pool中时,需要将数据页读入内存再进行更新操作,但是这会带来额外的IO开销。使用Change Buffer可以将这部分更新操作先进行缓存,当下次读入这些数据页时,更新操作会merge到数据页上。也有可能系统没有访问这些数据页,此时Change Buffer中的更新操作会被系统定期的sync到磁盘。

值得注意的是,Change Buffer只缓存对二级索引的更新操作。因为相较于主键索引的连续有序且唯一性,二级索引通常是不唯一的,且更新二级索引会有大量的随机IO操作,这对系统性能的影响很大,因此对这部分更新操作进行缓存的收益更加明显。

另外一个需要关注的问题是Change Buffer中的操作是如何持久化。在Innodb中,Change Buffer的更新操作和普通数据的更新操作类似,也会写redo log。最开始Change Buffer使用的是系统表空间,当数据页读入内存并进行merge操作后,系统会记录该数据页redo log并将其标记为脏页,该数据页的变更会被刷回磁盘。因此,Buffer Pool中的更新操作最终都会持久化到磁盘中。

Log Buffer

Redo Log日志文件也需要相应的内存数据结构来进行缓存操作。Log Buffer就是用于缓存日志文件的内存空间,其空间大小可以通过数“innodb_log_buffer_size”来设定。通常来说,日志文件的每次更新都应该刷会磁盘,不然就会有数据丢失或不一致的风险。“innodb_flush_log_at_trx_commit”参数用于设置日志刷回磁盘的频率,其默认值为1,即每次事务提交时,都会记录日志,并将其刷回到磁盘。该参数值为0时,日志写入和刷回磁盘的操作为每秒1次;该参数值为2时,每次事务提交时都会写入Log Buffer,但Log Buffer更新到磁盘的操作为每秒1次。

image

Innodb系统架构

上图是Innodb内存数据和磁盘数据结构的示意图,左边就是本文主要学习的内存数据结构。之前也提到,Buffer Pool在Innodb中的作用类似于操作系统中的Page Cache,在图中也可以看到,Buffer Pool绕过了系统缓存,通过O_DIRECT方式来读写数据。所以对Buffer Pool的管理,相当于是Innodb为数据库这种存储系统设计的缓存管理。而Log Buffer并没有使用Buffer Pool的空间,使用的是系统缓存。

小结

本文简要描述了Innodb Buffer Pool, Change Buffer, LogBuffer这三种内存数据结构,作为记录Innodb存储引擎的开篇内容相对基础,有疑问或感悟欢迎在留言区讨论。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容