We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
当插入辅助索引时,会出现随机插入的情况,此时mysql会离散的访问索引页,然后插入索引数据。因为存在随机的IO,如果存在大量的并发插入,会导致性能下降,所以出现了插入缓冲机制。对于辅助索引的插入或者更新,不是直接插入到索引页中,而是先判断插入的辅助索引页是否在缓冲池中,如果在,直接插入,否则先放入到一个insert buffer对象中。之后再以一定的频率进行insert buffer和辅助索引页子节点的merge操作。
这里说的是先判断插入的索引页是否在缓冲池中,但是mysql如何判断插入的是哪一个索引页呢?个人认为还是读磁盘上的该索引对应的B+树,找到该数据应该插入的地方,也就是对应的索引页。但是既然找到了插入的地方,为什么不直接插入?因为插入可能会造成索引节点的分裂,会有随机IO。而且对于同一索引节点的写入,可以利用insert buffer在后期直接一次写入merge,节省IO。
使用insert buffer的两个条件:
为什么索引不能是唯一的?因为若索引是唯一的,mysql为了检查一致性,还是要进行随机读取索引页,违背了设计插入缓存的初衷——为了防止随机IO读取索引页。
insert buffer的数据结构是B+树,全局只有一颗B+树,存放在共享表空间中,也就是ibdata1。 B+树的非叶子节点是Search key,构造结构为(space,marker,offset)。
当一个辅助索引要插入到(space,offset)中时,如果该页不在缓冲池中,则按上述规则构造一个search key,将该记录插入到insert buffer中。
但是如果该页一直在insert buffer中,不断有记录插入到同一个索引页中,那么该索引页的空间就会逐渐缩小,要出现B+树节点的分裂情况,这时就不能进行insert buffer了。所以,我们需要一个机制来管理每个页面的剩余空闲空间,这就是Insert buffer bitmap。每隔page_size个页面,就是一个Insert buffer bitmap page。例如:若page_size = 16384(16k),那么page_no为0,16384,32768,…的page,就是Insert buffer bitmap page,Bitmap page的功能,就是管理其后连续的page_size – 1个page的空间使用率。 每个辅助索引页在Insert buffer bitmap中占用4bit。
insert buffer什么时候真正合并到真正的辅助索引中?
针对第一点:
针对第三点: 若过去1s之内发生的I/O,小于系统I/O能力的5%,则主动进行一次Insert buffer的merge操作。Merge的页面数为系统I/O能力的5%,读取page采用async io模式。 每10s,必定触发一次insert buffer merge动作。Merge的页面数仍旧为系统I/O能力的5%。 如何选择insert buffer页?随机选择一个insert buffer页,读取该页中的space及之后所需要数量的页。
参考资料:《MySQL技术内幕-InnoDB存储引擎》 何登成的技术博客 InnoDB Insert Buffer实现详解
The text was updated successfully, but these errors were encountered:
No branches or pull requests
当插入辅助索引时,会出现随机插入的情况,此时mysql会离散的访问索引页,然后插入索引数据。因为存在随机的IO,如果存在大量的并发插入,会导致性能下降,所以出现了插入缓冲机制。对于辅助索引的插入或者更新,不是直接插入到索引页中,而是先判断插入的辅助索引页是否在缓冲池中,如果在,直接插入,否则先放入到一个insert buffer对象中。之后再以一定的频率进行insert buffer和辅助索引页子节点的merge操作。
这里说的是先判断插入的索引页是否在缓冲池中,但是mysql如何判断插入的是哪一个索引页呢?个人认为还是读磁盘上的该索引对应的B+树,找到该数据应该插入的地方,也就是对应的索引页。但是既然找到了插入的地方,为什么不直接插入?因为插入可能会造成索引节点的分裂,会有随机IO。而且对于同一索引节点的写入,可以利用insert buffer在后期直接一次写入merge,节省IO。
使用insert buffer的两个条件:
为什么索引不能是唯一的?因为若索引是唯一的,mysql为了检查一致性,还是要进行随机读取索引页,违背了设计插入缓存的初衷——为了防止随机IO读取索引页。
insert buffer的数据结构是B+树,全局只有一颗B+树,存放在共享表空间中,也就是ibdata1。
B+树的非叶子节点是Search key,构造结构为(space,marker,offset)。
当一个辅助索引要插入到(space,offset)中时,如果该页不在缓冲池中,则按上述规则构造一个search key,将该记录插入到insert buffer中。
但是如果该页一直在insert buffer中,不断有记录插入到同一个索引页中,那么该索引页的空间就会逐渐缩小,要出现B+树节点的分裂情况,这时就不能进行insert buffer了。所以,我们需要一个机制来管理每个页面的剩余空闲空间,这就是Insert buffer bitmap。每隔page_size个页面,就是一个Insert buffer bitmap page。例如:若page_size = 16384(16k),那么page_no为0,16384,32768,…的page,就是Insert buffer bitmap page,Bitmap page的功能,就是管理其后连续的page_size – 1个page的空间使用率。
每个辅助索引页在Insert buffer bitmap中占用4bit。
insert buffer什么时候真正合并到真正的辅助索引中?
针对第一点:
针对第三点:
若过去1s之内发生的I/O,小于系统I/O能力的5%,则主动进行一次Insert buffer的merge操作。Merge的页面数为系统I/O能力的5%,读取page采用async io模式。
每10s,必定触发一次insert buffer merge动作。Merge的页面数仍旧为系统I/O能力的5%。
如何选择insert buffer页?随机选择一个insert buffer页,读取该页中的space及之后所需要数量的页。
参考资料:《MySQL技术内幕-InnoDB存储引擎》
何登成的技术博客 InnoDB Insert Buffer实现详解
The text was updated successfully, but these errors were encountered: