zoukankan      html  css  js  c++  java
  • mysql redo日志与刷脏

    1.redo日志

    为了在服务器崩溃时保证数据安全并提升系统性能,innodb存储引擎首先会将提交的事物内容记录到redo日志,而对实际数据文件修改则放在以后,批处理方式刷盘。redo日志像逻辑的存储场所,它循环使用多个文件。(ib_logfile0、ib_logfile1、ib_logfile2)

    innodb_log_file_size     #各日志文件大小

    innodb_log_files_in_group     #日志文件的个数,innodb最终可用的日志大小为innodb_log_file_size *innodb_log_files_in_group

     innodb_log_group_home_dir    #日志目录

    redo日志空间越大,innodb缓冲池中就可以停留更多的“脏页”。这样,innodb缓冲池的脏页就可以更大批量的新式刷新到磁盘。由于mysql5.5redo日志可用空间最大为4GB,所以在拥有大容量缓存的innodb中,工作效率并不高。mysql5.6开始允许用户设置4GB以上redo日志,innodb_log_file_size *innodb_log_files_in_group组合最大可以为512GB.这样,当在拥有大量缓存空间时脏页可以更有效发挥写缓冲作用。

    2.刷脏

    在innodb中处理用户查询后,其结果在内存空间的缓冲池已经发生变化,但是还未记录到磁盘。这种页面称为脏页,将脏页记录到磁盘的过程称为刷脏。刷脏分两种算法:flush-list(依据时间管理缓冲池中更改页面的列表)LRU-list(用于管理缓冲池中非常用页面的列表)

    (1)flush-list根据RDBMSredo日志的工作方式(write Ahead Log),在redo日志与脏页中,redo日志总要首先被完全刷到磁盘时,才能再次使用与该脏页相关的redo日志槽。此时为了在缓冲池中快速查找脏页,会根据脏页的修改时间顺序维护一个链表,该链表称为flush-list。

    (2)假如innodb的缓冲池全部由数据页和索引填满,innodb缓冲池没有空闲空间。此情形下,一个新查询到来,这时为了执行该查询,innodb存储引擎必须从缓冲池中删除几个已经加载的页面,innodb不会随意删除,innodb管理着LRU-list链表,需要删除时会从该链表选择。LRU-list维护着最近不常用的页面列表。LRU-list分为两个区域,MRU和LRU。MRU位于LRU-list的5/8之前,其余部分为LRU。也就是5/8之前存储着常用的页面,其余3/8为不常用页面(可以修改innodb_old_blocks_pct系统变量值控制MRU与LRU之间的分割点,默认值为5/8)。删除内容会在最不常用链表的末端删除几个页面。删除之前会进行刷脏。

    mysql5.6开始引入了page cleaner线程,专门负责刷脏:

    1)缓冲池无空闲空间时,就会依据LRU_list将最近最少使用的页面刷新到磁盘,要 刷脏页的顺序由LRU_list管理。

    2)flush_list链表会依据变更的时间顺序对脏页进行管理,并使用xxx算法刷新flush_list中的页面。

    mysql5.6的innodb针对LRU_list刷新引入了innodb_lru_scan_depth系统变量,该变量可以针对每个缓冲池实例分别进行设置,查找page cleaner线程要刷新的脏页时。可以借助该变量设定要在LRU_list中扫描的页数。IO比较闲的服务器可以设置大点,写入多,缓冲池大适当减小。

    innodb缓冲池中可保留的脏页数由redo日志大小总和确定,同样,flush_list中可保留的页面总量也由innodb中redo日志大小总和决定。

    为了在innodb的redo日志文件中留下适合大小的空闲空间,就要不断刷新flush_list中的脏页。但是刷新过多会导致缓冲池效率下降。如果刷新太慢,又很难保证innodb的redo日志有足够的空闲空间。当innodbredo日志中的空闲空间即将耗尽,mysql的所有查询都会进入阻止状态,innodb存储引擎会拼命将flush_list中的脏页刷新到磁盘。为了防止出现这一情况,在保证innodb redo日志有空闲空间的同时,又要让缓存保留适当脏页,并定期进行管理。

    mysql5.6的innodb提供了innodb_io_capacity与innodb_io_capacity_max以使后台线程可以控制脏页刷新。

    root@localhost:mysql3316.sock  14:14:28 [(none)]>show global variables like "innodb_io_capacity%";
    +------------------------+-------+
    | Variable_name          | Value |
    +------------------------+-------+
    | innodb_io_capacity     | 2000  |
    | innodb_io_capacity_max | 4000  |
    +------------------------+-------+

    innodb_io_capacity,与缓冲池中的脏页或change buffer的索引合并一样,需要将许多这样的数据记录到磁盘,这些工作全部由innodb后台线程负责处理。innodb的后台线程处理这些操作并写磁盘时,通过innodb_io_capacity可以限制允许的最大写磁盘页数。此值,若设置太大,缓冲池的脏数据会快速刷新到磁盘,设置太小,缓冲池的全部脏页数就会增加,redo空闲空间就会减少。

    innodb_io_capacity_max,与innodb redo日志的增长量相比,若脏页刷新延迟,innodb就会更激进的执行刷新工作,可能会超过innodb_io_capacity指定的IOPS值,这种危急情况下,innodb_io_capacity_max系统变量用于设置允许的最大iops,这样,即使发生IO爆发,也能保证磁盘IO不会耗尽所有系统资源。

  • 相关阅读:
    前插法创建带头节点的单链表
    利用Oracle数据库发送邮件
    关于如何给C#中的ListBox控件添加双击事件
    类似QQ表情的功能,包括动态绑定图片
    ASP.NET 缓存技术总结
    VS2008 快捷键大全
    Oracle 中union的用法
    C#找到Excel中的所有Sheetname的方法
    推荐一个学习XPath的网站
    Oracle游标使用大全
  • 原文地址:https://www.cnblogs.com/xxmysql/p/5754211.html
Copyright © 2011-2022 走看看