Innodb结构图
    Memory-structures - 图1
    Innodb内存结构
    1/buffer pool
    buffer pool用来缓存Innodb的表以及索引数据,在专用服务器上,通常分配80%的物理内存给buffer pool。

    buffer pool的LRU(least recently used)算法
    buffer pool是用LRU算法列表来管理的。当要把一个新页加入到buffer pool时,就会剔除一个旧的页。之前的新页中就会有一个变成旧页。

    Memory-structures - 图2
    New sublist是最近访问的页,Old sublist是最近不常访问的列。
    算法操作如下:

    1. 3/8的buffer pool被用来存放old sublist
    2. 中点(midpoint)是new sublist的尾与old sublist的头。
    3. 当Innodb读取一个新页时,它会自动插入到中点(old sublist的头部)。
    4. 访问old sublist中的页会使它变的更”新”,会把这个页移动到new sublist的头部。
    5. new sublist跟old sublist中的页都会随着其他页的更新而老化。

    默认情况下,一个查询会使页直接移动到new sublist。

    监控buffer pool
    使用show engine innodb status\G;语句

    mysql> show engine innodb status\G;
    ....
    ----------------------
    BUFFER POOL AND MEMORY
    ----------------------
    Total large memory allocated 137428992
    Dictionary memory allocated 116177
    Buffer pool size   8191
    Free buffers       7861
    Database pages     330
    Old database pages 0
    Modified db pages  0
    Pending reads      0
    Pending writes: LRU 0, flush list 0, single page 0
    Pages made young 0, not young 0
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 296, created 34, written 36
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    No buffer pool page gets since the last printout
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 330, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    

    各个字段的含义

    Name Description
    Total memory allocated The total memory allocated for the buffer pool in bytes.
    Dictionary memory allocated The total memory allocated for the InnoDB data dictionary in bytes.
    Buffer pool size The total size in pages allocated to the buffer pool.
    Free buffers The total size in pages of the buffer pool free list.
    Database pages The total size in pages of the buffer pool LRU list.
    Old database pages The total size in pages of the buffer pool old LRU sublist.
    Modified db pages The current number of pages modified in the buffer pool.
    Pending reads The number of buffer pool pages waiting to be read into the buffer pool.
    Pending writes LRU The number of old dirty pages within the buffer pool to be written from the bottom of the LRU list.
    Pending writes flush list The number of buffer pool pages to be flushed during checkpointing.
    Pending writes single page The number of pending independent page writes within the buffer pool.
    Pages made young The total number of pages made young in the buffer pool LRU list (moved to the head of sublist of “new” pages).
    Pages made not young The total number of pages not made young in the buffer pool LRU list (pages that have remained in the “old” sublist without being made young).
    youngs/s The per second average of accesses to old pages in the buffer pool LRU list that have resulted in making pages young. See the notes that follow this table for more information.
    non-youngs/s The per second average of accesses to old pages in the buffer pool LRU list that have resulted in not making pages young. See the notes that follow this table for more information.
    Pages read The total number of pages read from the buffer pool.
    Pages created The total number of pages created within the buffer pool.
    Pages written The total number of pages written from the buffer pool.
    reads/s The per second average number of buffer pool page reads per second.
    creates/s The average number of buffer pool pages created per second.
    writes/s The average number of buffer pool page writes per second.
    Buffer pool hit rate The buffer pool page hit rate for pages read from the buffer pool vs from disk storage.
    young-making rate The average hit rate at which page accesses have resulted in making pages young. See the notes that follow this table for more information.
    not (young-making rate) The average hit rate at which page accesses have not resulted in making pages young. See the notes that follow this table for more information.
    Pages read ahead The per second average of read ahead operations.
    Pages evicted without access The per second average of the pages evicted without being accessed from the buffer pool.
    Random read ahead The per second average of random read ahead operations.
    LRU len The total size in pages of the buffer pool LRU list.
    unzip_LRU len The length (in pages) of the buffer pool unzip_LRU list.
    I/O sum The total number of buffer pool LRU list pages accessed.
    I/O cur The total number of buffer pool LRU list pages accessed in the current interval.
    I/O unzip sum The total number of buffer pool unzip_LRU list pages decompressed.
    I/O unzip cur The total number of buffer pool unzip_LRU list pages decompressed in the current interval.

    2/change buffer
    change buffer是用来缓存那些由DML语句引起的二级索引的变化,但是二级索引页却不在buffer pool中。当再次查询时,change buffer中的页会合并到buffer pool中。
    Memory-structures - 图3
    二级索引通常都不是唯一的,并且二级索引的插入是相对随机的顺序。
    在内存中,change buffer是buffer pool的一部分。在磁盘上,当系统关闭时,缓存中存有索引的变化时会存到系统表空间。

    change buffer相关变量
    1/Innodb_change_buffering
    控制了什么样的操作语句会被缓冲到change buffer。
    枚举值:
    all 所有(默认)
    none 什么语句都不会缓存
    inserts 缓存insert语句
    deletes 缓存delete语句
    changes 缓存insert跟delete语句
    purges 缓存后台进行的物理删除

    2/Innodb_change_buffer_max_size
    控制change buffer的大小,这个值默认是25,意味着占buffer_pool的25%,最大可以设置50。

    监控change buffer

    mysql> show engine innodb status\G;
    ...
    -------------------------------------
    INSERT BUFFER AND ADAPTIVE HASH INDEX
    -------------------------------------
    Ibuf: size 1, free list len 0, seg size 2, 0 merges
    merged operations:
     insert 0, delete mark 0, delete 0
    discarded operations:
     insert 0, delete mark 0, delete 0
    Hash table size 34673, node heap has 0 buffer(s)
    Hash table size 34673, node heap has 0 buffer(s)
    Hash table size 34673, node heap has 0 buffer(s)
    Hash table size 34673, node heap has 0 buffer(s)
    Hash table size 34673, node heap has 0 buffer(s)
    Hash table size 34673, node heap has 0 buffer(s)
    Hash table size 34673, node heap has 0 buffer(s)
    Hash table size 34673, node heap has 0 buffer(s)
    0.00 hash searches/s, 0.00 non-hash searches/s
    ...
    

    3/自适应hash索引
    自适应hash索引可以在具有适当的工作负载组合和足够的缓冲池内存的系统上执行更像内存中的数据库,而不牺牲事务特性或可靠性。
    innodb_adaptive_hash_index控制是否开启(默认开启),如果需要关闭,在启动时加上—skip-innodb-adaptive-hash-index
    如果一张表全在内存中,使用hash索引将会增加查询效率。如果Innodb注意到创建一个hash索引可以加速查询,它会自动创建。对于多并发关联,或者使用like 通配符时,自适应hash索引将不会提高效率。
    在5.7中,自适应hash索引是分区的,默认分成8个,最大512个,由 innodb_adaptive_hash_index_parts变量控制。
    监控自适应hash索引

    mysql> show engine innodb status\G;
    ----------
    SEMAPHORES
    ----------
    OS WAIT ARRAY INFO: reservation count 2
    OS WAIT ARRAY INFO: signal count 2
    RW-shared spins 0, rounds 4, OS waits 2
    RW-excl spins 0, rounds 0, OS waits 0
    RW-sx spins 0, rounds 0, OS waits 0
    Spin rounds per wait: 4.00 RW-shared, 0.00 RW-excl, 0.00 RW-sx
    

    4/log buffer
    log buffer 用来缓存要写进日志文件的数据。它的大小由Innodb_log_buffer_size控制,默认是16MB。日志缓冲区的内容会定期刷新到磁盘。
    一个足够大的log buffer可以允许大事务在运行时不用在提交前将redo log写入到磁盘。因此可以节省磁盘的I/O

    Innodb_flush_log_at_trx_commit这个变量决定了如何将日志缓冲区的内容写到磁盘。

    Command-Line Format —innodb-flush-log-at-trx-commit=#
    System Variable innodb_flush_log_at_trx_commit
    Scope Global
    Dynamic Yes
    Type Enumeration
    Default Value 1
    Valid Values 0
    1
    2

    当这个值为0时,每秒将日志缓冲区的数据刷新到磁盘。
    当这个值为1时,每个commit就会将日志缓冲区的数据刷新到磁盘。
    当这个值为2时,每次commit都会保存,但是每秒将日志缓冲区的数据刷新到磁盘。
    为了保证事务的持久性与一致性,需要将这个Innodb_flush_log_at_trx_commit=1。0,2都是不保险的。

    Innodb_flush_log_at_timeout这个变量决定了写到磁盘的频率,这个变量的默认值是1,如果Innodb_flush_log_at_trx_commit=0,就意味着每1秒落盘一次。这个变量的取值范围是1-2700。