Oracle 下马观花看redo
《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条原则
计算日志缓冲区需要多少空间。
服务器进程获取重做复制锁存器。这用于通知将一些重做复制到日志缓冲区中。
获取重做分配锁存器。这是实际的锁存器,它将分配日志缓冲区中的空间。
日志缓冲区获取空间后释放重做分配锁存器。
Redo copy latch用于复制日志缓冲区中的Redo更改向量。
释放重做复制锁存器。
在复制完成并在缓冲区缓存中的缓冲区上应用它们之后,根据不同的条件,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团队
分享创造价值,分享创造快乐
Oracle 下马观花看redo的更多相关文章
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...
- 07 oracle 归档模式 inactive/current redo log损坏修复--以及错误ORA-00600: internal error code, arguments: [2663], [0], [9710724], [0], [9711142], [], [], [], [], [], [], []
07 oracle 归档模式 inactive/current redo log损坏修复--以及错误ORA-00600: internal error code, arguments: [2663], ...
- Oracle 阅读器-刚看完表空间回复的详细解释
(一) 当使用一个控制文件的备份恢复,例如下面的附图.使用备份控制文件恢复位置 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGVtb25zb24=/fo ...
- [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了
[译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 本文首发自:博客园 文章地址: https://www.cnblogs.com/yilezhu/p/ ...
- Oracle 了解 DDL 操作与 REDO 的关系
目录 了解 DDL 操作与 REDO 的关系 DDL是否会产生REDO 通过 10046 trace 来分析create 和drop 如果drop失败,redo的变化 了解 DDL 操作与 REDO ...
- Oracle调优之看懂Oracle执行计划
@ 目录 1.文章写作前言简介 2.什么是执行计划? 3.怎么查看执行计划? 4.查看真实执行计划 5.看懂Oracle执行计划 5.1 查看explain 5.2 explain执行顺序 5.3 访 ...
- php 替换 oracle 数据字段中“看不见”换行符号
工作需要,把oracle中的数据导出csv,导出代码如下:<?php$file_name = "申請書承認(予定休出).csv";header("Content-D ...
- ORACLE 本session产生的redo
select * from v$statname a ,v$mystat bwhere a.STATISTIC# = b.STATISTIC# and a.name = 'redo size';
- oracle 批量改temp/data/redo file的路径
批量生成修改路径的脚本.select 'alter database rename file ''' || name ||'''' || ' to '''|| substr(name,0,instr( ...
随机推荐
- React-Native开发之BUG 总结
本博客将详细记录在React-Native开发中所遇到的各种问题以及其解决方法. 个人感觉,React-Native开发初期真的是一脚一个大坑,分分钟被虐趴下. 不说了,直接上Bug 1.在Windo ...
- Spring Boot—07应用application.properties中的配置
方法1 @Value("${test.msg}") private String msg; 方法2 @Autowired private Environment env; Stri ...
- linux 文件搜索命令locate及updatedb
windows 搜索工具Everything是根据NTFS日志来搜索的,所以速度特别快 locate 类似于windows的Everything,搜索速度比较快 如果没有locate命令,可安装 yu ...
- Linux服务器安装redis数据库教程
前面小Alan给大家说了jdk的安装,这篇跟大家聊聊redis非关系型数据库在Linux服务器的安装. redis简单介绍 REmote DIctionary Server(Redis) 是一个由Sa ...
- Bootstrap框架。
什么是 Bootstrap Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更 ...
- 将 ExpressRoute 线路从经典部署模型转移到 Resource Manager 部署模型
本文概述将 Azure ExpressRoute 线路从经典部署模型转移到 Azure Resource Manager 部署模型的效果. Azure 当前使用两种部署模型:Resource Mana ...
- mysql root更改远程登录
mysql> select user,host from mysql.user; +---------------+-------------+ | user | host | +------- ...
- SqlServer触发器实现表的级联插入、级联更新
首先建立两张表,分别为test1与test2,期望在更改test1的时候,test2的相关记录能够同时做出更改.假定test1与test2的表结构相同,如下表所示 name age 触发器实现 ...
- 如何在 OS X 中安装 ruby
如何在 OS X 中安装 ruby 软件包下载 链接: http://pan.baidu.com/s/1mgMil5I 密码: tiqg 安装 http://brew.sh/ 1. 先安装 brew( ...
- amazon interview
I'll be sitting for an Amazon interview in 3 months. Which website should I use to practice: SPOJ, H ...