首页 >> 软件 >> Redo 会话从产生到写入会话文件

Redo 会话从产生到写入会话文件

2023-04-19 软件

buffer 和历史口述元数据中都。

mtr 的用途可正因如此打包举例来话说 Redo 历史口述这么比较简单,它还但会对 SQL 分派操控过程中都 mtr 须要访问的 Buffer Pool 中都的页加针、改寄给页中都的数据、释放针,本文我们只简述 Redo 历史口述,对于 mtr 就不再进一步展开了。

还有一个概念须要解释一下,历史口述第一组就是一个 mtr 中都的所有历史口述。

三、存储 log buffer

mtr 中都举例来话说必分隔的操控都完成之后,就该顺带交了,mtr 顺带交操控过程中都要脱的第一件事就是把它里头面临时放于的举例来话说 Redo 历史口述存储到 log buffer 中都。

一个管理工作中都确实但会包含多个 mtr,mtr 的顺带交和管理工作的顺带交不是一个概念,不用误读。

下面话说到在 MySQL 8.0 中都,往 log buffer 里头寄给历史口述不须要下班独自前进(得到局部性针),多个客户端内核可以同时存储。

这个无针化时设计是通过在 log buffer 中都为每个 mtr 中都的 Redo 历史口述加设室内空间构建的,每个 mtr 都有一段统称自己的室内空间,各自往自己专属的室内空间内存储历史口述,相互之间就不阻碍了。

客户端内核的 mtr 往 log buffer 寄给 Redo 历史口述前,但会必先得到一段标识。

以也就是话说系统中都已激发的最大标识(SN)作为 start_sn,加上本次要往 log buffer 中都存储的 Redo 历史口述的元组数(len),取得 end_sn(end_sn = start_sn + len)。

start_sn ~ end_sn 就是本次要存储 log buffer 的 Redo 历史口述的标识下行。

得到 start_sn、end_sn 的操控过程是质子操控,多个内核之间不但会显现出来冲突,不但会得到到有复合的标识下行。

获得 start_sn ~ end_sn 只是第一步,还须要进行一次转成,把标识(SN)转成为历史口述标识(LSN),取得一个 LSN 的适用范围:start_lsn ~ end_lsn,这个适用范围完全一致着 log_buffer 中都为 mtr 即将存储的 Redo 历史口述加设的室内空间。

SN 是月内某个下一场,InnoDB 中都实际激发的 Redo 历史口述元组数。

SN 按照 496 元组再分,再分后每 496 元组,加上 12 元组的头电子邮件、4 元组尾部检验码,取得 512 元组的 block,经过这样的转成之后,取得的十进制就是 LSN。

至此,存储历史口述到 log buffer 的准备岗位又往前前进了一步。

但是,别着急,只不过还要再进一步等等,如果 log buffer 中都剩余室内空间欠缺存储也就是话说 mtr 的 Redo 历史口述,那就须要等到 log buffer 中都的 Redo 历史口述被存储历史口述元数据,为也就是话说 mtr 的 Redo 历史口述加设室内空间才行。

这里头的存储历史口述元数据,只是调用了MS-DOS的寄给元数据原理,把 Redo 历史口述存储历史口述元数据的MS-DOS区块中都,历史口述元数据暂时还不但会创出到闪存上。

那怎么判断 log buffer 中都究竟有室内空间呢?

要问道这个问题,我们须要必先简述一个物件 log_sys.write_lsn,回应 LSN 少于 log_sys.writen_lsn 的历史口述都早就存储到历史口述元数据区块中都。

end_sn

如果要等,总不会之前等吧,等到什么时候是个头呢?

如果须要独自前进,客户端内核但会通话 log.write_events 意外事件,log buffer 中都有室内空间存储 Redo 历史口述之后,也就是话说客户端内核但会收到意外事件告知。

谁但会给这些独自前进的客户端内核发送到意外事件告知呢?后面但会有简述,商量独自往下看。

等到 log buffer 中都有室内空间之后,往里头面存储历史口述就很比较简单了,都只把 mtr 中都的 Redo 历史口述拷贝到 log buffer 中都就完事了。

读完之后,还须要根据 mtr 的 start_lsn 在 recent_written.m_links 中都寻找完全一致的 SLOT,然后把 mtr 的 end_lsn 存储这个 SLOT,回应这个 mtr 早就把它的全部 Redo 历史口述存储 log buffer 了。

如果根据 start_lsn 在 recent_written.m_links 中都寻找的 SLOT 打算被其它 mtr 采行,也就是话说这个客户端内核但会采行循环 + 较宽夏末 20 微秒的作法,直到 SLOT 可以采行。

下面两段涉及到 recent_written 的简述,大家看了确实但会真是一头雾水,必先不用着急,有个模糊印象就行。因为这两段逻辑上是在寄给历史口述到 log buffer 这个阶段发生的,所以这里头必需要顺带一下露个贴,差不多九成个位,简要简述在第四部分。

话说完了存储 Redo 历史口述到 log buffer,我们离开客户端内核独自前进 log buffer 中都有室内空间存储它的 Redo 历史口述,这个独自前进操控过程是个躺平的操控过程,在这个操控过程中都,客户端内核除了独自前进意外事件告知,其它事情啥也不脱。

在客户端内核看来,独自前进的操控过程中都日子静好,但是,生灵起初很难日子静好,它感受到的日子静好,无非是因为有人替它沙包前进。

谁在沙包前进?

那是另一个默默岗位的内核,它的名字叫作 log_writer,它是一个搬运工,一个专门把 log buffer 中都的 Redo 历史口述存储到历史口述元数据的内核。

log_writer 内核只调用MS-DOS寄给元数据原理,把 Redo 历史口述存储历史口述元数据,不但会创出到闪存上,此时,Redo 历史口述还在历史口述元数据的MS-DOS区块中都。

年中,就是 log_writer 内核的主场了。

四、存储历史口述元数据

log writer 内核把 log buffer 中都的 Redo 历史口述存储历史口述元数据区块,存储的这一段 Redo 历史口述必需是周内的,下方不会显现出来或许。

上一个步骤中都,不同客户端内核可以并行把各自 mtr 中都的 Redo 历史口述存储 log buffer 中都,解决了存储速度慢的问题,同时也带来了解决办法。

不同客户端内核的 Redo 历史口述量确实不一样,有的内核但会必先读完,有的内核后读完,如果某一个适用在全球性上,头部的历史口述读完了,尾部的历史口述也读完了,下方的历史口述还没读完,这就显现出来了或许。

举个例证,论点有 3 个不同的客户端内核,各有一个 mtr 要顺带交,我们把这 3 个客户端内核的 mtr 分别叫作 mtr 10、mtr 11、mtr 12。

mtr 10 的 Redo 历史口述九成用 200 元组,LSN 适用范围是 start_lsn(2097252) ~ end_lsn(2097452)。 mtr 11 的 Redo 历史口述九成用 12045 元组,LSN 适用范围是 start_lsn(2097452) ~ end_lsn(2109497)。 mtr 12 的 Redo 历史口述九成用 300 元组,LSN 适用范围是 start_lsn(2109497) ~ end_lsn(2109797)。

每一个 mtr 的 end_lsn 只不过是不统称它的,而是统称下一个 mtr,是下一个 mtr 的 start_lsn。所以,每个 mtr 的 LSN 适用范围是一个左闭右开下行,例如:mtr 10 [2097252, 2097452)。

mtr 10、mtr 12 的历史口述比较小,mtr 11 的历史口述比较大,确实但会存在这样的情况,mtr 10、mtr 12 的历史口述都早就全部存储 log buffer,mtr 11 的历史口述只有一部分存储了 log buffer,下方是存在或许的。

因为存在或许,log_writer 内核不会把 mtr 10 ~ 12 的 Redo 历史口述都存储历史口述元数据,只能把 mtr 10 的 Redo 历史口述存储历史口述元数据。

等到 mtr 11 的 Redo 历史口述全部存储 log buffer 之后,才能把 mtr 11 ~ 12 的 Redo 历史口述一起存储历史口述元数据。

那它怎么究竟月内到哪个左边的历史口述是周内的,可以存储历史口述元数据的呢?

只不过我们都能很快一心到用一个变量把这个左边口述下来就好了。

没错,InnoDB 也是这么脱的,有序历史口述某类(log_sys)中都,有一个 recent_written 物件,这个物件也是个某类,它有一个物件 m_tail(log_sys.recent_written.m_tail),用来口述 log buffer 中都少于哪个 LSN 的历史口述都是周内的。

究竟了用什么记,现在有个关键问题,那就是怎么记?

recent_written 某类,有个物件 m_links(recent_written.m_links),这是个数第一组,当前有 1048576 个类型,每个类型是一个 SLOT,每个 SLOT 九成用 8 元组,总共九成用 8M 程序运行。

m_links 的每个 SLOT 完全一致 log buffer 中都的一个 LSN,每个客户端内核的 mtr 往 log buffer 中都存储它的全部 Redo 历史口述之后,但会根据 start_lsn 在 m_links 中都寻找一个 SLOT,并把 end_lsn 存储这个 SLOT。

还是从下面的 mtr 10 ~ 12 为例,当 mtr 10 把它的所有 Redo 历史口述全部存储 log buffer 之后,根据 start_lsn(2097252) 寻找完全一致的 SLOT 并存储 end_lsn(2097452)。

SLOT 负数 = start_lsn(2097252) % SLOT 总数(1048576) = 100。

m_links[100] = end_lsn(2097452),m_links[101 ~ 299] 完全一致着 LSN 2097253 ~ 2097451,也统称 mtr 10 的适用范围,不过这个下行只是用来不论如何的,mtr 10 并不但会往其中都的 SLOT 存储 LSN。

必忽视详述:严格来说,因为 m_links 被都是外侧构件循环、重复采行,每个 SLOT 都有确实曾经被其它 mtr 存储过 end_lsn。

对于 mtr 10 来话说,除了 start_lsn 完全一致的 SLOT(m_links[100])的取值是 end_lsn(2097452) 之外,其它 SLOT(m_links[101 ~ 299])的取值确实是 0,也确实是之后的某个 mtr 存储的 end_lsn。

如果 SLOT 的取值是之后的某个 mtr 存储的 end_lsn,这个 end_lsn 一定是少于相等 mtr 10 的 start_lsn 的。

当 mtr 12 把它的所有 Redo 历史口述全部存储 log buffer 之后,根据 start_lsn(2109497) 寻找完全一致的 SLOT 并存储 end_lsn(2109797)。

SLOT 负数 = start_lsn(2109497) % SLOT 总数(1048576) = 12345。

m_links[12345] = end_lsn(2109797),m_links[12346 ~ 12644] 完全一致着 LSN 2109498 ~ 2109796,也统称 mtr 12 的适用范围,这个下行内 SLOT 的取值确实为 0 或者少于相等 start_lsn(2109497) 的十进制(确切状况可以参考 mtr 10 的详述)。

此时,mtr 11 的 Redo 历史口述还很难全部存储 log buffer,m_links[300 ~ 12344] 完全一致着 LSN 2097452 ~ 2109496,统称 mtr 11 的适用范围,这个下行内 SLOT 的取值确实为 0 或少于相等 start_lsn(2097452) 的十进制(确切状况可以参考 mtr 10 的详述)。

话说完了 mtr 10 ~ 12 的稳定状态,年中就要正式简述 Redo 历史口述存储历史口述元数据的关键步骤了:根据 recent_written.m_links 寻找 log buffer 中都周内的历史口述下行。

必先来回忆一下:

recent_written.m_tail,回应 log buffer 中都少于 recent_written.m_tail 的历史口述都是周内的。 log_sys.write_lsn, 回应 log buffer 中都少于 log_sys.write_lsn 的历史口述都早就存储历史口述元数据了。

论点,此时 recent_written.m_tail = 2097252,这是 mtr 10 的 start_lsn,回应 mtr 10 之后的 mtr 往 log buffer 中都存储的 Redo 历史口述早就是周内的了。

log_writer 内核年中从 m_tail 完全一致的 LSN(2097252)开始,追寻更大适用范围的周内历史口述下行。

量度 m_tail 完全一致的 SLOT 负数 = m_tail(2097252) % SLOT 总数(1048576) = 100。

加载 SLOT 100(负数为 100 的 SLOT)的取值,取得 2097452,这是 mtr 10 的 end_lsn,也是 mtr 11 的 start_lsn,详述 mtr 10 的历史口述已存储 log buffer。

LSN

独自追寻,量度 m_tail 完全一致的 SLOT 负数 = m_tail(2097452) % SLOT 总数(1048576) = 300。

加载 SLOT 300 的取值,取得 0,详述 mtr 11 还很难把 Redo 历史口述全部存储 log buffer 了,本次追寻更大适用范围的周内历史口述下行终止,m_tail 保持为 2097452 连续性。

log_writer 内核可以把 log buffer 中都 LSN

然后,log_writer 内核或 log_write_notifier 内核但会告知打算独自前进往 log buffer 中都 LSN

为了大大降低 log_writer 内核的开销,告知客户端内核这个逻辑上做了区分:

如果只有一个客户端内核打算独自前进往 log buffer 中都 LSN

如果有多个客户端内核打算独自前进往 log buffer 中都 LSN

第三部分话说过,如果客户端内核须要独自前进 log buffer 中都有室内空间存储它的 Redo 历史口述,这个客户端内核但会通话 log.write_events 意外事件,log_writer Brown log_write_notifier 内核就是通过这个意外事件告知客户端内核的。

严格来说,客户端内核通话的是 log.write_events[slot],slot 是对 mtr 的 start_lsn 取模量度取得的,量度公式是这样的:slot = start_lsn % recent_written.m_links 的 SLOT 总数(当前 1048576)。

通话到确切的 slot 上是为了情况下每个客户端内核只但会送达到 log.write_events 意外事件中都和自己有关的告知。

过了比较大但会,log_writer 内核又要开始岗位了,此时,mtr 11 中都的全部 Redo 历史口述都存储 log buffer 了。

上次终止时,recent_written.m_tail = 2097452,其完全一致的 SLOT 负数为 300,这次从 SLOT 300 开始独自追寻。

加载 SLOT 300 的取值,取得 2109497,这是 mtr 11 的 end_lsn,也是 mtr 12 的 start_lsn,详述 LSN

独自追寻,量度 m_tail 完全一致的 SLOT 负数 = m_tail(2109497) % SLOT 总数(1048576) = 12345。

加载 SLOT 12345 的取值,取得 2109797,这是 mtr 12 的 end_lsn,也是 mtr 12 之后的下一个 mtr 的 start_lsn,详述 LSN

独自追寻,量度 m_tail 完全一致的 SLOT 负数 = m_tail(2109797) % SLOT 总数(1048576) = 12645。

加载 SLOT 12645 的取值,取得 0,详述 Redo 历史口述周内的下行到这里头暂时终止,m_tail 保持为 2109797 连续性。

log_writer 内核可以把 log buffer 中都 LSN

然后,log_writer 内核或 log_write_notifier 内核但会激活 log.write_events 意外事件,告知打算独自前进往 LSN

五、历史口述元数据剪盘

Redo 历史口述从 log buffer 存储历史口述元数据中都,并不是都只就寄给到闪存元数据中都了,而是但会必先进入历史口述元数据在MS-DOS的区块中都,还须要经过剪盘操控才能最终寄给到闪存上的历史口述元数据中都,成为长久化时的历史口述。

Redo 历史口述元数据剪盘,也是由专门的内核完成的,这个内核是 log_flusher。

log_flusher 内核的常规岗位是大约米/秒分派一次剪盘操控。

有序历史口述某类(log_sys)中都有一个物件 flushed_to_disk_lsn 回应少于 log_sys.flushed_to_disk_lsn 的 Redo 历史口述都早就创出到闪存上的历史口述元数据中都了。

下面我们还顺带到了另一个物件 log_sys.write_lsn,回应 log buffer 中都少于 log_sys.write_lsn 的历史口述都早就存储历史口述元数据了。

每次分派剪盘操控时,对比这两个物件的取值,就能判断出来历史口述元数据区块中都只不过有新的 Redo 历史口述须要剪盘。

如果 log_sys.write_lsn 大于 log_sys.flushed_to_disk_lsn,详述须要剪盘,否则本次不须要分派剪盘操控,log_flusher 内核可以美好的躺平大约 1s 左右,然后独自前进下一次星期到了,再进一步进行都只的逻辑上判断,具体究竟须要剪盘。

不出意外的话,log_flusher 内核就是这么比较简单平凡,日复一日,年复一年的飞轮单调的岗位着。

但是,这毕竟不不符剧情的发展,单调的故事中都显然但会时不时显现出来点兴奋的剧情。

log_flusher 内核除了常规的米/秒分派一次剪盘操控,还但会通话一个意外事件:log.flusher_event,通过这个意外事件和此番建立联系,接受受控兴奋。

我们来看一个带给 log_flusher 内核兴奋场景:

innodb_flush_log_at_trx_commit = 1 时,管理工作每次顺带交的时候,都心急火燎的,不确实心平气和的等着 log_flusher 米/秒分派一次剪盘操控,必需让 log_flusher 立马痛快脱活(管理工作但会激活 log.flusher_event 意外事件),把管理工作中都激发的 Redo 历史口述剪盘,然后,管理工作才能向客户端押上。

innodb_flush_log_at_trx_commit = 2 时,管理工作心急火燎的某类就不是 log_flusher 内核了,而是 log_writer 内核,因为这种场景下,管理工作只须要独自前进 log_writer 内核把它的 Redo 历史口述存储历史口述元数据区块就可以了,不须要独自前进剪盘。

管理工作执意 log_flusher 分派剪盘操控之后,但会独自前进剪盘操控完成。独自前进操控过程是通过通话 log.flush_events[slot] 意外事件构建的。

slot 是对管理工作中都最终一个 mtr(一个管理工作可以包含多个 mtr)的 end_lsn 取模量度取得的,量度公式是这样的:slot = end_lsn % recent_written.m_links 的 SLOT 总数(当前 1048576)。

slot 的作用是情况下每个客户端内核只但会送达到 log.flush_events 意外事件中都和自己有关的告知。

剪盘操控完成后,log_flusher 内核或 log_flush_notifier 内核但会告知打算独自前进 LSN

为了大大降低 log_flusher 内核的开销,告知客户端内核这个逻辑上做了区分:

如果只有一个客户端内核打算独自前进本次剪盘结果,log_flusher 内核随手就告知这个客户端内核了。

如果有多个客户端内核打算独自前进本次剪盘结果,log_flusher 内核但会让 log_flush_notifier 内核去告知独自前进本次剪盘结果的所有客户端内核。

六、归纳

Redo 历史口述是以历史口述第一组为单位存储 log buffer 和历史口述元数据的,每个历史口述第一组的 Redo 历史口述都出自于一个 mtr。

多个客户端内核的 mtr 以无针的作法并行往 log buffer 里头存储 Redo 历史口述,只须要存储之后量度出来 mtr 中都 Redo 历史口述的 LSN 适用范围,通过这个 LSN 适用范围在 log buffer 中都针定一段下行,多个客户端内核针定的下行不一样,不但会显现出来冲突。

log_writer 内核把早就存储 log buffer 的 Redo 历史口述存储历史口述元数据,须要情况下 Redo 历史口述是周内的,InnoDB 用 log_sys.recent_written 某类中都的 m_links 数第一组、m_tail 物件来辅助 log_writer 内核寻找周内的历史口述下行。

log_writer 内核把 log buffer 中都的 Redo 历史口述存储历史口述元数据之后,但会告知独自前进 log buffer 为它加设室内空间的客户端内核,或者让 log_write_notifier 内核告知客户端内核。

log_flusher 内核米/秒分派一次剪盘操控,同时还通话了 log.flusher_event 意外事件,用于送达受控兴奋,激活它在瞬时剪盘岗位的时候也必需更及时的剪盘。

如果 log_sys.write_lsn 大于 log_sys.flushed_to_disk_lsn 详述须要分派剪盘操控,否则不须要。

log_flusher 内核分派完剪盘操控之后,也但会告知独自前进剪盘操控完成的客户端内核,或者让 log_flush_notifier 内核告知客户端内核。

最终,放上一张连续性作法上图,希望必需有助于大家认知 Redo 历史口述剪盘的连续性作法上。

作者丨操盛春

来源丨社会公众号:一树一溪(ID:bigspring52)

dbaplus社交欢迎广大应用人员投稿,投稿电话号码:editor@dbaplus.cn

更多精彩内容

dbaplus社交最新一期录播【腾讯Kubernetes集群运维演进与思考】将于8月17日晚8点开播,腾讯杭州研究院-基础平台中都心资深联合开发工程师-岳文远将带大家详述腾讯内部Kubernetes集群运维的的发展历程,社交面对高效管理大量异构集群的需要,如何设计集群运维平台以构建高能效运维和智能化时管理,并归纳运维系统演进的经验,为基础云原生的发展趋势预测集群运维更进一步的的发展朝著。复制客户端到微信,可都只免费观看哦~

关于我们

dbaplus社交是圆桌Database、BigData、AIOps的企业级专业社交。资深大咖、应用脱货,每天精品原创发表文章推送,每周线上应用社交,每月线下应用沙龙,每季度GdevopsBrownDAMS行业大但会。

关切社会公众号【dbaplus社交】,得到更多原创应用发表文章和陈奕迅物件下载

伤口老是不愈合怎么办
小孩子积食怎么调理最有效
治疗关节炎有什么好方法
蒙脱石散有什么功效
便秘了怎么办
TAG:文件
友情链接