当前位置: 首页 > 科技观察

MySQL表数据应该多久刷新一次?

时间:2023-03-19 20:42:46 科技观察

前言事情是这样的,我在某狐的邀请回答中看到了这个问题:-然后我想也没想就把答案记了下来:这个其实是需要通过MySQL后台线程来刷新,在Buffer中修改的PagesPool中的将被标记为脏页并放入一个链表(Flushlinkedlist)中。然后MySQL在满足条件时启动后台线程将Flush列表中的脏页刷新到磁盘。需要满足的条件是:脏页数达到BufferPool中页数的**10%。当然10%这个值是可变的,是通过配置项innodb_max_dirty_pages_pct_lwm配置的。默认值为10%,这个值也必须小于另一个配置innodb_max_dirty_pages_pct的值(90%**)。至于启动多少个线程,是由另一个变量innodb_page_cleaners控制的,默认是4个,一般这个不会改。就是这样。然而,后面的一个兄弟说:“我不知道你在说什么”。后来回过头来看,当时写的确实有点太跳了。过了一会,再看的时候,就不太连贯了,打算再把这件事弄清楚。1、表数据我们的“短文”讨论了【MySQL表数据应该多久刷新一次】。从这个标题,我们可以拆分成两个问题:什么刷盘,什么时候刷盘,我们分开讨论。2.什么刷入磁盘好像有点废话,肯定是把数据刷入磁盘。所以我们更需要讨论的是【数据以何种形式刷入磁盘】。在InnoDB中,页是数据管理的最小单位。当MySQL以InnoDB作为存储引擎运行时,表中的数据会逐行逐页组织起来,放入BufferPool中。该页面的数据存储在缓冲池中。当DML语句(即CRUD)语句改变表数据时,数据所在的页会被标记为脏页。InnoDB会使用一个叫做[Flushlinkedlist]的结构来存储这些脏页。任何一个页面被放入链表意味着它需要刷新到磁盘,但不会立即刷新。与RedoLog等其他InnoDB日志一样,这些日志也有自己的刷新策略。例如,对于RedoLog,它的刷新策略可以用下图来表示:如果参数为0,则RedoLog每秒写入并刷新到磁盘。如果该参数为1,则RedoLog将在每次事务提交后刷新到磁盘。参数为2,每提交一个事务,都会写入OS缓存,然后每秒将OS缓存中的数据刷新到磁盘。Flush链表也有自己的策略。3.什么时候刷盘接上一节,策略是:当脏页数达到BufferPool中页数的**10%**时,会触发Flush中的脏页刷盘链表到磁盘。比如BufferPool一共有100页。如果脏页数达到10,就会启动后台线程触发磁盘刷新。当然,[10%]的值是可以配置的,可以通过mysql配置项innodb_max_dirty_pages_pct_lwm进行调整,但是默认值为10%。但是我们调整的值不能超过某个最大值,这个最大值由innodb_max_dirty_pages_pct指定,默认值为90%。也就是说,刷量阈值默认是10%,如果需要自定义,最大值不能超过90%。4.谁来负责刷盘?如前一节所述,将启动线程来执行此操作。这是毫无疑问的。我们需要注意的是会启动多少个线程来做这个。答案是4,我们也可以通过配置项innodb_page_cleaners来改变,但是一般我们不会改变这个值。这里就来说说这一点。