-----------------------------------------
--Lerning Content :Oracle 下马观花看redo
--Author :如人饮水冷暖自知
--版权所有 :首发于ORA-600团队微信公众号:

《Oracle 蓝莲花》:转载请注明出处以及作者

技术分享交流QQ群:851604218

2019年3月中旬,有技术分享交流课程,欢迎加群探讨

-----------------------------------------

引言

下马看花-redo

领导毛主席在《在鲁迅艺术学院的讲话》中说过这样一段话:俗话说,走马看花不如驻马看花,驻马看花不如下马看花,我 希望你们都要下马看花。是的,有时候技术学到一定阶段,很多细节知识确实需要我们 穷波讨源,细致的研究,今天和大家聊得是alert 日志中出现Private strand flush not complete提示,这提示背后的故事.

1

背景介绍

截图1为简单的QQ沟通

初步了解DBA排错思路和现场问题情况

截图2为alert日志中具体的信息提示

截图3为前台应用给出的另一个报错信息

AWR报告信息提示:

一、分析思路:

1.对于log file switch (checkpoint incomplete)等待事件,容易误导DBA的排查思路,awr报告里该等待事件平均等待 601.22毫秒,占用当前dbtime 31%,同时db cpu占用dbtime的比例达到41%。这里我们不妨分析这个等待事件产生的成因,log file switch (checkpoint incomplete)指的是当redo需要向下一组redo group切换的时候,发现下组日志是active活动状态的,简单的说就是下组日志中对应的一些buffer cache中的脏块压根没有写入到数据文件中,因此必须等待这些dirty block被flush完毕 后,才可以复用下一组redo group

2.既然是把dirty block flush到datafile,那么自然是dbwn的工作,实际我们需要更多关注的是dbwn这个进程的写io负载情 况,那么awr里有8.3g的控制文件io负载是为什么,其实是DBW本身的io问题导致 LGWR不断查询control 文件获取redo 状态,获 取状态最根本的目的就是想知道究竟redo切换是否成功,所以后台产生大量控制文件io操作。

3.在以前的文章中我们分享过log file sync等待事件,写redo很慢,从而导致gc buffer busy acquire /release 等待事件,其 实这个就比较方便定位,只要我们做了addm,可以看到诸如如下的提示:Waits on event “log file sync” were the cause of significant database wait on “gc buffer busy” when releasing a data block. Waits on event“log file sync” in this instance can cause global cache contention on remote instances,那么基本可以确认gc buffer busy的源头是log file sync(虽然本质上不是),那么优先解决log file sync的问题。

二、工作原理分析

历史追溯

oracle 9i时代,企业业务数据还没井喷,无论是事务还是日志生成量都相对较少,那个年代没有所谓大数据的概念,基本都 维持在一次变更,一条数据,一次内存分配即可完成的状态,随着企业业务数据激增,尤其oltp系统,老的redo机制已经无法满足 高并发,大写入量的需求,到10g版本以后oracle推出了private redo 和imu,也就是in-memory undo的机制,这样一来,一个 进程就可以以整个事务的方式去工作,生成所有的改变向量,并将它们存入私有重做日志缓冲区,也就是private redo log buffer 中,当事务提交时,进程将存于私有重做日志缓冲区的记录复制到公共的重做日志缓冲区,这时,跟传统的重做日志缓冲区工作原 理保持一致,那么写到重做日志文件的过程,一个进程在一个事务里只需要获得一次公共的redo allocation latch,而不是每次变 更都要获取一次latch。

赏花望月-IMU

既然是下马看花,为了方便大家理解,我们至少要搞懂几个事情,才能做到真正意义的赏花望月,imu机制带来的in memory undo latch是否影响数据库负载,是否有威胁,同时分析重做日志文件,搞清楚redo entry都记录了什么,同时我们还要 分析x$kcrfstrand x$ktifp理解各种实例活动信息之间的关联关系,这里涉及的技术知识点比较多,由于篇幅原因,和大家分享两个 相对重要的:

1. 关于redo方面增量的基础结构由两组内存结构组成,一组是x$kcrfstrand私有redo区域,主要处理前滚改变向量, 另一组x$ktifp imu区域,处理undo改变向量,私有redo区域里面也包含传统的公共重做日志缓冲区,因此如果查询这个固化视图 发现有两类不同的信息,不要担心,是正常现象。

2. x$ktifp表示imu区域中的池个数,取决于持有事务的细节v$transaction的数组大小,它由oracle的参数 transactions设定,但是这个参数通常随session 或者processes参数调整自动更新,基本上,池的个数默认为transactions/10,比 如transactions是1000,那么池的个数就是100,每个池是由自己的imu latch受保护的。

3. x$ktifp中的每一条记录在x$kcrfstrand中都有与之对应的一条私有redo记录,不过x$kcrfstrand还会涉及其他信 息,公共的redo记录个数由cpu_count参数决定,算法是ceiling(1 + cpu_count/16)

4. x$kcrfstrand中的每一条私有重做记录都由自身的redo allocation latch来保护,每一条公共的重做记录都由传统 的redo copy latch保护,每个cpu一个redo copy latch

三、下马看花第一步

根据oracle官方介绍为了减少redo allocation latch等待,在oracle 9i中,引入了log buffer的并行机制。其基本原理就 是,将log buffer划分为多个小的buffer,这些小的buffer被成为strand(为了和之后出现的private strand区别,它们被称之为 shared strand)。

每一个strand受到一个单独redo allocation latch的保护。多个shared strand的出现,使原来序列化的redo buffer分配变成了并行的过程,从而减少了redo allocation latch等待。shared strand的初始数据量是由参数log_parallelism控 制的;

在10g中,该参数成为隐含参数,并新增参数_log_parallelism_max控制shared strand的最大数量; _log_parallelism_dynamic则控制是否允许shared strand数量在_log_parallelism和_log_parallelism_max之间动态变化,这里需

要注意_log_parallelism在12c版本已经弃用

三人行必有我师

​       每一个shared strand的大小  = log_buffer/(shared strand数量) 关于shared strand的数量设置,16个cpu之内最大默认为 2,当系统中存在redo allocation latch等待时,每增加16个cpu可以考虑增加1个strand,最大不应该超过8。并且 _log_parallelism_max不允许大于cpu_count

Oracle  日志缓冲区7条原则

  1. 计算日志缓冲区需要多少空间。

  2. 服务器进程获取重做复制锁存器。这用于通知将一些重做复制到日志缓冲区中。

  3. 获取重做分配锁存器。这是实际的锁存器,它将分配日志缓冲区中的空间。

  4. 日志缓冲区获取空间后释放重做分配锁存器。

  5. Redo copy latch用于复制日志缓冲区中的Redo更改向量。

  6. 释放重做复制锁存器。

  7. 在复制完成并在缓冲区缓存中的缓冲区上应用它们之后,根据不同的条件,LGWR可能会开始将内容写入日志文件中。从 V$latch_childeren 可以看到我们的数据库目前有多少个锁存。这是我的12c机器的输出

插播广告,来看一个实验

实验小结:

1、即使我们尝试了insert,也没有标记为dirty的缓冲区。Oracle确实获得了一些buffer来保存我们的更改,但是它们没有被标 记为dirty。但当我们发出commit时,所有缓冲区都被标记为dirty。为什么

2、这就是刚才工作原理,以及概念介绍的IMU/ Private Redo Strands机制

3、与Oracle需要保护重做的原因相同,它还必须保护Undo,以确保块的旧内容也被保存。这将需要访问块,并在稍后更改事 务表以记录更改。交易记录可以从V$transaction中看到。为了直接访问undo段头块,我们还可以检查X$KTUXE,对于 V$transaction的基表,可以使用X$KTCXB。从oracle 10g开始,oracle确实使用了Undo块,但是在专门创建的私有内存区域中可 以使用它们

正如刚才我们介绍的,每个池由一个锁存器维护,这个锁存器称为in memory undo latch。可以从V$latch_children中看到它们

工作原理不变,我们还可以在共享区域看到内存结构形态:

---IMU池分配在共享池中。我们更改的数据从内存撤消锁存器中的锁存器复制到这些池中。我们可以从V$latch中看到

----当我们修改数据时,oracle不会立即将数据应用到数据块上,而是通过这个IMU锁将数据分配到共享池中的IMU池中。这种 机制避免了撤销段头块的固定,也避免了在事务启动时立即使用的撤销数据块的固定。现在它们只在事务提交时使用。数据在池 中,只有从池中复制到缓冲区缓存。由于每个池被分配给一个事务,并由一个单独的锁存器维护,IMU池也在X$ktifp中进行了描 述。池的大小为65kb

---通过dml操作验证imu的刷新机制

四、下马看花第二步

No1

查看imu资源信息

No2

显示已经使用的imu buffer

No3

参数_log_private_mul

参数_log_private_mul指定了使用多少logfile空间预分配给Private strand。我们可以根据当前logfile的大小(要除去预分 配给log buffer的空间)计算出这一约束条件下能够预分配多少个Private strand

当logfile切换后(和checkpoint一样,切换之前必须要将所有Private strand的内容flush到logfile中,因此我们在alert log中可能会发现日志切换信息之前会有这样的信息:"Private strand flush not complete",这是可以被忽略的),会重新根据切 换后的logfile的大小计算对Private strand的限制

No5

参数_log_private_parallelism_mul用于推算活跃事务数量在最大事务数量中的百分比,默认为10。Private strand的数量不 能大于活跃事务的数量,我们刚才设置最高到383

五、问题定位

1、

通过工作原理分析我们明确了redo切换日志的时候所有的private strand 都必须刷新到当前日志,然后才能做下一组redo日志切换

2、

当我们看到alert中有诸如Private strand flush not complete提示的时候,其实本质问题就是还没有把所有的redo信息写到 redo日志文件的问题,strand其实就是处理redo的latch,允许进程利用多个 allocation latch 更高效地将 redo 写入 redo 缓冲区 的机制

3、

同时我们通过数据字典验证了解到初始分配的 strand 数量取决于 CPU 的数量,最少两个 strand,其中一个 strand 用于活 动的 redo 生成

4、

那么什么情况下我们需要关注这个问题呢,正常情况都是无需关注的,除非cannot allocate new log信息和advanced to log sequence信息之间有明显的时间差

5、

通过和现场DBA了解,当前redo设置为200m,分3组,这套库偏olap类型,有大事物串行写入操作,DBA介入调整了redo 日志组大小,后期继续关注。

6、

oracle mos提供了一个诊断助手的工具,帮助我们定位ORA-01555, ORA-30036, ORA-01628, ORA-01552报错信息,详 细的可以参考document :1575667.2

ORA-01562官方解释如下:

7、

表空间没有足够的连续空间来允许回滚/撤消段的扩展。当下一个区段大小大于最大的连续空间时,将引发扩展失败错误。 只有当对象试图扩展时,没有足够的可用连续空间时,才会生成此错误

ORA-01562排错思路

1、首先查询出可用的最大连续空间 select max(bytes) from dba_free_space where tablespace_name = 'UNDOTBS1';

2、默认情况下pct_increase为0,我们基于select next_extent, pct_increase from dba_rollback_segs where segment_name = segment number 12的名称;查询

3、尝试手动的合并相邻的空闲区段Alter tablespace XX coalesce;

4、尝试添加新的数据文件Alter tablespace XX add datafile ....    size ...

5、尝试resize操作Alter database datafile XX resize XX;

6、在手动模式下,可以尝试设置事务用户回滚段,强制大型事务使用大型回滚段,以克服ORA-1562。用户事务记录在回滚段 中。在用户提交更改之前,事务在回滚段中保持打开状态。SET TRANSACTION USER ROLLBACK SEGMENT

7、SET TRANSACTION USE ROLLBACK SEGMENT不会强制DDL使用特定的回滚段。它只对DML有效

六、总结


总结

汇报人:ORA-00600


1、我们所做的任何一个改变都会产生一次对imu latch的访问,这并不意味大的latch争用,因为oracle只是用一个imu latch代 替了redo allocation latch和redo copy latch,所以理论上,至少将latch竞争减少了一半。imu latch有很多子latch,每个latch负责一个imu的内存区域池,这里我没做过更细致的研究。

     2、同时我们也了解到新机制两种redo allocation latch机制,一类为保护私有redo线程也就是private redo thread,另一类保 护公共的redo线程,也就是public redo thread,每个线程都有自己的latch。

3、对于Private strand flush not complete提示更多无需关注,此信息表示我们在尝试切换时,尚未完全将所有 redo 信息写 入到日志中。它本质上类似于checkpoint not complete,不同的是,它仅涉及到正在被写入日志的redo。在写入所有 redo 前, 无法切换日志。

——如人饮水冷暖自知

ORA-00600

​        可靠的网络协议,如TCP/IP,将数据缓冲到发送和接收缓冲区中,同时从下层和上层协议发送和接收数据。这些缓冲区的大小通过影响流量控制决策而影响网络性能

3.2  RECV_BUF_SIZE & SEND_BUF_SIZE

RECV_BUF_SIZE和SEND_BUF_SIZE参数指定与Oracle Net连接相关联的套接字缓冲区的大小。为了确保连续的数据流和更好地利用网络带宽,使用RECV_BUF_SIZE和 SEND_BUF_SIZE参数指定会话接收和发送操作的I/O缓冲区空间限制。RECV_BUF_SIZE和SEND_BUF_SIZE参数值不必匹配,但应该根据环境设置。

在客户机上配置I/O缓冲区空间:

注意

注意:

1.一般只设置RECV_BUF_SIZE参数就足够了。如果客户端正在发送大型请求,那么还可以设置SEND_BUF_SIZE参数。这些参数是在客户机的sqlnet.ora文件中设置的

3.5  在服务器上配置I/O缓冲区大小

在服务器上配置I/O缓冲区大小

因为数据库服务器向客户机写入数据,所以在服务器端设置SEND_BUF_SIZE参数通常就足够了。如果数据库服务器正在接收大型请求,那么还可以设置RECV_BUF_SIZE参数。

要配置数据库服务器,就需要在监听文件中设置缓冲区空间大小

3.6  下面是sqlnet.ora文件的配置

RECV_BUF_SIZE=65536

SEND_BUF_SIZE=65536

3.7  TDU

TDU是Oracle Net中用于将数据分组的默认数据包大小。理想情况下,TDU参数应该是SDU参数的倍数,这里对TDU不做太多介绍了亲们。感兴趣去oracle官网看吧

3.8  客户端或服务器平均等待时间

下面的查询显示了一种从Oracle的角度评估网络性能的方法,其中客户机或服务器的平均等待时间是根据服务器或客户机分别等待消息的时间记录

3.9  客户机和服务器实际传输字节数

下面的查询显示了客户机和服务器进程的平均等待时间以及实际传输的字节数

注意

注意:

1.内容实在太多了,我只粘贴了部分内容

2.经验之谈:

Oracle调优网络使用的关键是尽可能少地使用网络。可能最重要的因素是将SQL语句组合成事务。例如,如果要获取10个行,一次发送10个行的请求比为每一行发送10个请求更有效。由于网络比数据库服务器或客户机慢得多,所以这一点应该是显而易见的。

Part

4

正式进入

SQL*Net message to client

SQL*Net more data to client

等待事件调优环节


基础的一些技术指标介绍完毕以后,我们来进入正式的SQL*Net message to client,另一个是SQL*Net more data to client等待事件调优环节。

注意:

刚才我们已经明确说过SQL*Net类型等待事件的重点,这些等待并不意味着Oracle的等待,而是通常空闲的等待事件或网络等待。

4.1 等待事件说明

当服务器进程向客户端发送数据或消息并等待回复时,就会发生类似SQL*Net message to client等待事件。原则上其实等待时间就是等待TCP响应的时间。这个等待通常被认为是一个空闲的等待事件,因为服务器进程正在等待其他的响应。就调优而言,如果单个等待时间很高,那么很可能无法在服务器上进行改进,而是在其他地方。

如果总等待量很高,但是单个等待量很小,那么等待量可能是由于网络接入的方式问题。

4.2  工作原理猜想

对于SQL*Net事件等待,Oracle使用SDU(会话数据单元,这个技术指标刚才我们介绍过了)写入到TCP套接字缓冲区的SDU缓冲区。

如果数据大于会话数据单元的初始大小,那么需要发送多个数据块。如果有更多的数据要发,那么在每批数据发送后,会话将等待SQL*Net more data to client上。

4.3  如何诊断?

那么如何诊断SQL*Net message to client和SQL*Net more data to client ???

注意:仅仅包括个人看法,诊断等待的最佳方法,我个人认为是运行10046。一个进程或一个sql都可以使用10046跟踪。例如下面一个傻瓜式的简单举例:

注意

注意:

通过10046获得跟踪,如果觉得不好定位,可以TKPROF格式化一下,这里可以看到单个等待'SQL*Net message to client'的时间通常很短(在这种情况下,总等待时间小于1微秒)。等待会被记录下来,但是我们可以清晰的在10046中看到max wait和total waited都是0,等待并不一定是性能问题或引起关注的重点。

4.4   arraysize

如果应用程序使用大量数据,请考虑增加应用程序中的arraysize。如果使用较小的arraysize来获取数据,那么查询将使用多个fetch调用,每个调用都将等待'SQL*net message to client'事件。

4.4.1  何为arraysize ?

SQL*PLus中的默认ARRAYSIZE是15。这将在分析跟踪文件时显示,方法是将返回的行数除以SQLNet往返次数,作为应用程序中使用的默认大小。当向应用程序返回一组值时,

ARRAYSIZE指定要返回的行数。因为这指定了要返回的数组大小,所以它直接影响满足数据请求所需的往返次数。

4.4.2 举例说明

注意:

大致判断一下,总行数是93151行,该表总共有1792个block,那么相当于将近60行数据就占用一个block。

注意:

实际上oracle使用了1639个数据块,我们也可以看到实际上每个数据块存37行,49行,53行数据,都是不等的,这里就不一一列举了。有人会为,那1792个数据块哪里来的,忽悠我呢?来看如下查询

注意:

oracle总共分配了29个extent,其中16个区是以8K数据块为单位,另外13个extent是以128K数据块为单位的,也就是说 (16 * 8) +(13*128)=1792的结果

.........

执行计划

统计信息

注意:

缺省arraysize为15的情况下产生的SQL*Net to client为 5298168

........

执行计划

统计信息

注意:

arraysize调整到200后产生的SQL*Net to client为4249913

........

执行计划

统计信息

注意:

arraysize调整到500后产生的SQL*Net to client为4198916

Part

5

总结

今天通过一些简单的技术指标和大家分享一下sql*net类型等待事件调优的心得,希望通过这篇并不完美的文章可以在日常工作中帮到各位

请输入标题请输入文字

雁过留影,爱过留心

LOVE

一起感受滑雪的魅力

扫描如下QQ群二维码,加入600团队

分享创造价值,分享创造快乐


请输入标题

转载于:https://www.cnblogs.com/ora-600/p/10456434.html

Oracle 下马观花看redo相关推荐

  1. Oracle新建的用户看不到表,Oracle 创建用户及数据表的方法

    Oracle 创建用户及数据表的方法 更新时间:2009年09月25日 23:13:29   作者: 刚开始学习oracle的朋友可以看下,这个是基础了. 一.概念 1. 数据库 (Database) ...

  2. oracle成本类型,Oracle 1053事件 主要看是成本怎么计算的

    Oracle 1053事件 主要看是成本如何计算的? Apress.Cost.Based.Oracle.Fundamentals. 看中文翻译版看的很吃力. 当初不知10053事件,看完该书花费了很长 ...

  3. oracle lz压缩,LZ:Oracle热备期间过量Redo生成控制

    很多人都有这样的了解,为了防止热备期间的分裂块问题,Oracle在热备过程中会对修改块进行全块的Redo记录. 请大家注意:此外还存在一个隐含参数可以控制这个行为: SQL> SELECT x. ...

  4. imu oracle,问一个关于IMU REDO的问题~

    > Private strand的redo allocation latch 和Shared strand的redo allocation latch是不一样的latch么 I'd love t ...

  5. [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了

    园子里关于ASP.NET Core Web API的教程很多,但大多都是使用EF+Mysql或者EF+MSSQL的文章.甚至关于ASP.NET Core Web API中使用Dapper+Mysql组 ...

  6. Oracle主库、备库redo日志管理

    文章目录 官方参考: 1.添加日志组以及日志成员 3.删除日志组或成员 3.1.日志的重定位及重命名 3.2.清空日志文件组 3.3.删除日志成员 3.4.删除日志组 5.删除单实例数据库多余节点的日 ...

  7. 全栈溯源、mAPM、金融性能、Oracle VS. MySQL:看APM技术专场有哪些干货

    在日益复杂的应用环境中,网络.移动端.浏览器端.服务端的性能问题种类繁多,如何精准的定位问题根源,并留住用户是关键问题.尤其是云计算平台的普及使用,更是对应用性能的追踪和优化提出了新的拷问.在此前提下 ...

  8. Oracle调优之看懂Oracle执行计划

    1.文章写作前言简介 之前曾经拜读过<收获,不止sql调优>一书,此书是国内DBA写的一本很不错的调优类型的书,是一些很不错的调优经验的分享.虽然读了一遍,做了下读书笔记,觉得很有所收获, ...

  9. Oracle 1053事件 主要看是成本如何计算的?

    Apress.Cost.Based.Oracle.Fundamentals. 看中文翻译版看的很吃力. 当初不知10053事件,看完该书花费了很长的时间! 10053事件 1 创建测试表 create ...

最新文章

  1. VC解析XML--使用CMarkup类解析XML
  2. Linux Mint 13 root登录
  3. iphone降级_今年 iPhone 将支持手写笔?乔老爷哭了!
  4. 通过History Trends Unlimited通过统计笔记本Chrome浏览器Top10网页历史访问量(截止至2021.11.23)
  5. 老李分享:Android -自动化埋点 2
  6. 曼哈顿距离最小生成树
  7. LeetCode 121:买卖股票的最佳时机 思考分析
  8. java的svn插件maver_项目版本管理工具---MAVENSVN
  9. Linux通过端口查找tomcat的路径
  10. springboot的使用html页面及css、js路径的配置
  11. 水晶报表基础入门——6.交叉报表设计技术
  12. 【HDU5536】Chip Factory(01字典树+01字典树上删除某个数)
  13. 怎样用一个鼠标和键盘控制两台电脑
  14. 增选54位院士,京东副总裁梅涛等18位华人入选!
  15. directx修复工具win7_魔兽争霸3不能初始化DirectX,怎么解决?说白了就是在游戏安装包下载之后,无法正常运行程序。...
  16. jeb 高级教程之动态调试
  17. 空手套白狼的生意有哪些?利用信息差获取收益的项目!锦鱼课堂
  18. 码医自学法V2.2(附名老中医)
  19. 【计算机科学基础】元宇宙的最新技术、应用和挑战
  20. Android 打造炫目的圆形菜单 秒秒钟高仿建行圆形菜单

热门文章

  1. fs-extra 操作文件
  2. 查看计算机远程端口,CMD下查3389远程端口
  3. portmap全网最稳定的端口转发工具
  4. 03pe修改计算机名称,[U盘PE教程]03PE注册表修改与优化总结
  5. unity中使用htc vive
  6. 0.96寸OLED屏硬件驱动电路
  7. 汽车轮毂检测,轮毂检测方案,轮毂视觉检测,深度视觉系统
  8. 【甘道夫】Spark1.3.0 Cluster Mode Overview 官方文档精华摘要
  9. html定义布尔类型,布尔类型.html
  10. 【CF1257C】Dominated Subarray map的合理使用