Innodb - JiyangM/spring GitHub Wiki

  • 支持事物
  • 行锁
  • 外键
  • mvcc
  • 隔离级别
  • 插入缓冲
  • 二次写
  • 自适应哈希索引
  • 欲读
  • 聚簇索引

A:一个master 线程(innodb 几乎在这个线程上实现有所有功能)

B:一个lock 监控线程

C:一个错误监控线程

D:四个IO线程(insert buffer thread\log thread\write thread\read thread)


mysql内存结构-缓冲池

应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache)里,避免每次都去访问数据库。 操作系统,会有缓冲池(buffer pool)机制,避免每次访问磁盘,以加速数据的访问。 MySQL作为一个存储系统,同样具有缓冲池(buffer pool)机制,以避免每次查询数据都进行磁盘IO。

  • 缓冲池(InnoDB buffer pool)
    • data page
    • index page
    • insert buffer
    • lock info
    • 自适应哈希索引
    • 数据字典信息
  • 重做日志缓冲(redo log buffer)
  • 额外的缓冲池

1.查看缓冲池信息

使用MySQL命令”show variables like ‘innodb%pool%’;“可以查看InnoDB缓存池的相关参数信息。

InnoDB_buffer_pool_size: 用于设置InnoDB缓存池(InnoDB_buffer_pool)的大小。 InnoDB缓存池的大小对InnoDB整体性能影响较大,如果当前的MySQL服务器专门用于提供MySQL服务,应尽量增加InnoDB_buffer_pool_size的大小,把频繁访问的数据都放到内存中来,尽可能减少InnoDB对硬盘的访问,争取将InnoDB最大化成为一个内存型存储索引的访问,争取将InnoDB最大化成为一个内存存储引擎。

InnoDB_buffer_pool_instances: 默认值是1,表示InnoDB缓存池被划分到一个区域。适当地增加该参数(例如将该参数值设置为2),此时InnoDB被划分成为两个区域,可以提升InnoDB的并发性能。如果InnoDB缓存池被划分成多个区域,建议每个区域不小于1GB的空间。

InnoDB_additional_mem_pool_size: 指定InnoDB用来存储数据字典和其他内部数据结构的缓存大小,默认值是2MB。InnoDB表的个数越多,该参数的值就应该设置得越大;当InnoDB用完缓存空间时,InnoDB就会操作系统申请内存空间,并向错误日志写入一条警告信息。

2.缓冲池内部数据结构

InnoDB在内存中维护一个缓存池用于缓存数据和索引。缓存池可以被认为一条长LRU链表,该链表又分为2个子链表,一个子链表存放old pages(里面存放的是长时间未被访问的数据页),另一个子链接存放new pages(里面存放的是最近被访问的数据页面)。其余为new pages占用,如图下图所示。靠近LRU链表头部的数据页表示最近被访问,靠近LRU链表尾部的数据页表示长时间未被访问,而这两个部分交汇处成为midpoint。 当用户需要访问数据时,InnoDB首先会在InnoDB缓冲池查找数据,如果缓冲池中没有数据时,InnoDB会将硬盘上的数据块插入到InnoDB缓存池中;如果InnoDB缓冲池已满,InnoDB通过LRU算法清楚InnoDB缓存池中个别数据块。每当有新数据块需要加载到InnoDB缓冲池中时,该数据块应变为‘数据页’被插到midpoint的位置,并声明为old数据页。那么old数据页什么时候能移动到new Page链表中呢?

(1)当InnoDB_old_blocks_time的参数值设置为0时。当old部分的数据页被访问到时,该数据页会被提升到链表的头部,并被标记为new数据页。

(2)当InnoDB_old_blocks_time的参数值大于0时(以1000毫秒或者1秒为例)。old部分数据页插入缓冲池后,1秒之后被访问,该数据页会被提升到链表的头部,并被标记为new数据页。在刚插入到一秒内,即便old部分的数据页被访问,该数据页也不会移动到new链表的头部。

使用MySQL命令show variables like ‘innodb_old%’;可以查看InnoDB缓冲池结构的参数信息

innodb_old_blocks_pct:控制old page子链表在LRU链表中的长度。

innodb_old_blocks_time:控制old page子链表的数据页移动到new page 子链表中的时机。

3.缓冲池数据预读

MySQL服务启动一段时间后,InnoDB会将经常访问的数据(包括业务数据,管理数据)置入InnoDB缓冲池中,即InnoDB缓冲池保存的是频繁访问的数据(简称热数据)。当InnoDB缓冲池的大小是几十GB甚至是几百GB时,由于某些原因(例如数据库定期维护)重启MySQL服务,如何将之前InnoDB缓冲池中的热数据重新加载到InnoDB缓冲池中?简单地说:如何对InnoDB缓冲池进行预热,以便于MySQL服务器快速地恢复到重启MySQL服务之前的性能状态?

从5.6版本开始,MySQL支持关闭MySQL服务时将内存中的热数据保存到硬盘,MySQL重启后首先将硬盘中的如数据加载到InnoDB缓冲池中,以便缩短warmup进程的时间,提高业务繁忙高并发时的效率。使用MySQL命令show variables like ‘%innodb%pool%’;‘可以查看有关InnoDB缓冲池预热功能参数设置。

innodb_buffer_dump_at_shutdown: 默认为关闭OFF。如果开启该参数,停止MySQL服务时,InnoDB将InnoDB缓冲池中的热数据保存到本地硬盘。

innodb_buffer_pool_load_at_startup: 默认为关闭OFF。如果开启该参数,启动MySQL服务时,MySQL将本地热数据加载到InnoDB缓冲池中。

innodb_buffer_pool_load_now: 默认为关闭OFF。如果开启该参数,停止MySQL服务时,以手动方式将InnoDB缓存池中的热数据保存到本地硬盘。

innodb_buffer_pool_filename: 如果开启InnoDB预热功能,停止MySQL服务时,MySQL将InnoDB缓冲池中的热数据保存到数据库根目录中,默认文件名为ib_buffer_pool.

innodb_buffer_pool_load_aborr: 默认为关闭OFF。如果开启该参数,即便开启InnoDB预热功能,启动MySQL服务室,MySQL也不会将本地硬盘的热数据加载到InnoDB缓冲池中。

3.缓冲池数据预读失效 缓冲池污染

https://blog.csdn.net/weixin_40869022/article/details/103020194


https://blog.csdn.net/wuhenyouyuyouyu/article/details/93377605 https://blog.csdn.net/alexdamiao/article/details/51590118 https://www.sohu.com/a/322957463_178889