MySQL InnoDB简单架构图

InnoDB内存与线程

show engine innodb status

注:

  • Buffer pool size为show engine innodb status语句显示的Buffer pool size乘以16的大小,因为这里的单位是页,每个页默认为16k。

  • Free buffers + Database page != Buffer pool size,因为这里是LRU算法管理的页,还有其他例如锁信息等是不需要LRU算法管理的,但是也会占用一部分Buffer pool size。

  • InnoDB中使用的LRU算法并不是普通的LRU算法,添加了midpoint insertion strategy,即插入位置不在LRU列表的首位,而是在由innodb_old_blocks_pct配置项控制的距离尾端的相应位置处。

    如下,默认在尾部的3/8位置处:

    mysql> show variables like 'innodb_old_blocks_pct';
    +-----------------------+-------+
    | Variable_name         | Value |
    +-----------------------+-------+
    | innodb_old_blocks_pct | 37    |
    +-----------------------+-------+
    1 row in set (0.12 sec)
    
    
  • Checkpoint策略比较复杂,暂时先不放在这里。

  • 缓冲池信息可以通过INNODB_BUFFER_POOL_STATS,INNODB_BUFFER_PAGE_LRU查询。

  • 不同版本可能有区别,我实验的版本是MySQL5.6.37

一个单位,代表了InnoDB在任何时间在磁盘(数据文件)和内存(缓冲池)之间的传输数据量。一页可以包含一个或多个行,这取决于每行的数据量。如果一个行放入一个完整单页不合适,InnoDB会建立一个额外的指针式的数据结构,目的是让这个行的信息存储在一个页中,应该是让指针指向该页。

在页中存放更多数据的一个方式是使用压缩的行格式。对于使用了BLOB和大文本的字段,压缩的行格式允许这些大的列和其余的列分开存储,对于没有引用到这些列的查询减少I/O压力和内存使用。

When InnoDB reads or writes sets of pages as a batch to increase I/O throughput, it reads or writes an extent at a time.(这块不懂)

在MySQL实例内部,所有的数据结构遵循同样的页大小。

页大小

在MySQL5.5及以后的版本中,每个InnoDB页的大小固定为16k。这个值体现了一个平衡:能保存尽可能多的数据行,同时能保证尽可能减少的性能压力与尽可能少的传输额外的数据到内存中。其他的值未测试或不支持。

在MySQL5.6开始,对于InnoDB实例的页大小也能被设置为4k,8k或16k,通过innodb_page_size配置项设置。在MySQL5.7.6,InnoDB也支持32k和64k页大小。对于这两个大小,ROW_FORMAT=COMPRESSED不支持,只能支持到16k。

页大小在创建数据库实例的时候设置(实例简单理解就是MySQL 进程,不要理解成数据库或表),之后保持恒定,同样的页大小应用于所有的表空间,包括系统表空间,单表空间,通用表空间。关于表空间,具体可查看我之前的文章。

更小的页大小对性能有帮助,因为磁盘设备使用更小的块,尤其是SSD设备的工作负载受硬盘限制,例如在线事务处理应用,这种应用场景对性能要求高,更小的块本身有利于SSD,同时也有更少的行被更新,更少的数据被复制到内存,写入磁盘,加锁等。

(完)