暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle等待事件“日志文件并行写入”更改

原创 fritshoogland 2020-01-02
1059

这篇文章是关于如何测量“日志文件并行写入”事件的时间。这对于Oracle数据库中任何更改活动的性能调整都很重要,因为使用默认提交设置,提交更改的前台会话将在等待事件“日志文件同步”中等待,该事件是等待日志编写器活动,其中,等待事件“日志文件并行写入”始终是IO所用时间的指示器。

日志文件同步

首先:前台会话通常在提交等待日志编写器将其更改向量写入联机重做日志文件时等待等待事件“日志文件同步”。总是假设会出现“日志文件同步”是错误的。如果日志编写器设法将磁盘上的SCN增加到前台会话的提交SCN或超出该SCN,则不会出现“日志文件同步”等待事件。
我发现没有“日志文件同步”等待事件,因为我人为地降低了提交会话的速度。然而,随着Oracle代码的并行性的改进,甚至随着硬件层降低写延迟(特别是持久内存)的改进,这种情况在不久的将来可能会出现。至少11.2.0.4和更高版本是这样的(可能更早,但这些是我验证过的版本)。

日志文件并行写入

然而,这篇文章是关于在很多情况下导致“日志文件同步”时间的罪魁祸首的事件:它是关于“日志文件并行写入”等待事件,该事件发生在日志编写器中(当日志编写器本身写入时,它可以将其委托给日志编写器工作进程LGnn),这通常由Oracle数据库调谐器进行测量,以验证在前台会话显示高“日志文件同步”等待指示正在等待日志编写器的情况下日志编写器IO延迟。

我在查看logwriter的代码路径,使用intel pin tool s的“调试跟踪”工具,并在Linux、非ASM、Oracle 19.5上使用Tanel Poder的snaper,在logwriter进程上使用开始和结束快照。我将log writer设置为single logwriter模式(“_use_single_logwriter”=true),并执行了redo,这肯定会被logwriter接收。

在那里,我注意到统计数据表明发生了写操作,而没有“日志文件并行写入”等待事件。很奇怪…所以我深入研究了功能发生的情况。这些是我找到的函数:https://gitlab.com/snippets/1926207

重要的是:

–在函数ksfdaio()中提交IO请求:

ksfdaio>ksfdgo>ksfd_skgfqio>skgfqio>skgfr_lio_listio64>io_submit

–并在函数ksfdblock()中读取IO请求结果(“reaped”):

ksfdblock>ksfdpoll>ksfdwtio>skgfrwat>skgfrliopo>io-getevents

但根本不叫等待事件!*
与早期版本相比,这是一个明显的变化,在早期版本中,日志编写器写入始终会产生“日志文件并行写入”等待事件。但这种变化是什么时候发生的?为了回答这个问题,我安装了版本12.1.0.2(没有补丁)来查看代码路径,找到了:https://gitlab.com/snippets/1926211

重要的是:
–调用wait接口:kslwtbctx()
–在函数ksfdgo()中提交IO请求:

ksfd_sbio>ksfdgo>ksfd_skgfqio>skgfqio>skgfr_lio_listio64>io_submit

–并在函数ksfdwtio()中读取IO请求结果(“reaped”):

ksfd_sbio>ksfdwtio>skgfrwat>skgfospo>skgfrliopo>io_getevents

–等待接口结束:kslwtectx()

啊!所以一个明显的变化!那么这种变化是什么时候发生的呢?我安装了12.2.0.1,找到了相同的“等待”代码路径,然后安装了18.3,找到了等待的代码路径。所以变化可能发生在甲骨文19!所以我安装了19.3,再次找到了等待的代码路径!!那是PSU 19.4还是19.5的变化?我安装了19.5,也找到了等待的代码路径。

O.M.G.为什么我在同一版本的两个数据库中看到不同的行为?好吧,我设置了一些未记录的参数,所以我在新安装的数据库中复制了这些参数……它没有改变。

还有什么不同?嗯…一个是多租户数据库,另一个不是…但这肯定不会改变IO代码路径??当然这很容易检查,所以我删除了非CDB数据库并创建了一个CDB数据库,现在它显示了相同的“非等待”代码路径。

因此,显然,在多租户模式下使用oracle数据库会改变IO代码路径行为。我检查了版本中的代码路径,发现这个变化出现在12.2.0.1.0中,所以本质上是在Oracle12.2中(Oracle18和19实际上是Oracle12.2.0.2和Oracle12.2.0.3)。为了澄清这一点:我在12.1.0.2中没有发现这个变化。

这是否意味着等待事件“日志文件并行写入”根本不显示?不,如果io_提交后的调用io_getevents未返回所有提交的io,则它必须等待,此时调用等待接口,然后进入阻塞io_getevents调用,因此实际等待是计时的。此代码片段显示如下:https://gitlab.com/snippets/1926212

这将显示 ksfdblock>ksfdpoll>ksfdwtio>skgfrwat>skgfrliopo>io getevents,返回0(这意味着它在完成队列中找不到任何IOs),然后返回ksfdpoll函数,调用等待接口kslwtbctx,然后再次潜水到io u getevents,但现在处于阻塞模式等待io。

我还重复了对ASM的测试,它显示了完全相同的(非)等待行为。

结束语

对于Oracle版本12.1.0.2直至19.5,等待事件“日志文件并行写入”既包括IO请求的提交(io_submit调用),也包括等待所提交的IO完成(io_getevents调用)。这意味着在这种情况下,事件的等待时间是IO请求的总延迟,包括操作系统处理。

从版本12.2开始,仅在使用多租户选项的情况下进行更改,并且仅在提交的IO在提交后不可用时才显示等待事件“日志文件并行写入”,因此日志记录器进程具有等待他们。如果显示了等待,则事件的时间是从日志记录器过程的角度来看,IO完成的实际等待时间,而不是IO延迟时间。

当然,如果磁盘上具有不同延迟的多个日志组,则此等待事件将等待所有IO完成,这意味着它将乘以所有提交的IO中最慢的IO的时间。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论