sql语句执行时,产生一致性读。
什么是逻辑读? cpu在内存中读这些block的过程就叫做逻辑读(consistent get),在读的过程中产生的IO就是逻辑IO.逻辑读的过程中,是非常消耗cpu资源的.因此,执行sql的逻辑读越少越好.sql调优必须调整buffer get很大的sql语句
logical reads= consistent gets + db block gets,逻辑读其实是DB BLOCK GETS 和 consistents Gets 之和
DB block gets---当前请求的块数目
Consistent gets---数据请求总数在回滚段buffer中的数据一致性读所需要的数据块
Physical Reads---从磁盘读取数据块的数量(主要原因:buffer中不存在这些块;全表扫描;磁盘排序)
对于整个系统而言,我们用AWR报告为例。
1. 首先要关注的自然是Elapsed Time最高的那些,执行时间最长通常意味着消耗了更多的资源(无论这个资源是物理读还是逻辑读)
2. 其次关注的是Buffer Gets最多的SQL,这就是DB block gets+Consistent gets最多的SQL。大量的不必要的buffer gets会导致CPU time升高,在一个健康并且负载不低并且并不是以计算为主的系统中,CPU time占据首位的Top event通常是需要关注的。
3. 再其次关注Physical Reads最多的,并不是说物理读多的不容易调整,才放在后面关注,实际上是物理读通常都被基本的调优手段给调整完了,如果一个OLTP系统有大量的物理读,那么应该早就挂掉了,这是很明显的性能问题,会优先就调整好。
Oracle读取数据的方式有2种
1.物理读即是把数据从磁盘读入到buffer catch的过程。
通常情况下是,如果需要数据的时候发现不存在于buffer catch当中,即oracle就会执行物理读。
2.逻辑读取
逻辑读指的就是从(或者视图从)Buffer Cache中读取数据块。按照访问数据块的模式不同,可以分为即时读(Current Read)和一致性读(Consistent Read)。
(1)即时读 db block gets
即时读即读取数据块当前的最新数据。任何时候在Buffer Cache中都只有一份当前数据块。即时读通常发生在对数据进行修改、删除操作时。这时,进程会给数据加上行级锁,并且标识数据为“脏”数据。
(2)一致性读 consistent get
Oracle是一个多用户系统。当一个会话开始读取数据还未结束读取之前,可能会有其他会话修改它将要读取的数据。如果会话读取到修改后的数据,就会造成数据的不一致。
一致性读就是为了保证数据的一致性。在Buffer Cache中的数据块上都会有最后一次修改数据块时的SCN。
2.为什么要一致性读,为了保持数据的一致性
如果一个事务需要修改数据块中数据,会先在回滚段中保存一份修改前数据和SCN的数据块,然后再更新Buffer Cache中的数据块的数据及其SCN,并标识其为“脏”数据。
当其他进程读取数据块时,会先比较数据块上的SCN和进程自己的SCN。如果数据块上的SCN小于等于进程本身的SCN,则直接读取数据块上的数据;
如果数据块上的SCN大于进程本身的SCN,则会从回滚段中找出修改前的数据块读取数据。通常,普通查询都是一致性读。
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2013-01/77747.htm
3.一致性读
什么时候需要cr块呢,那就是select语句在发现所查询的时间点对应的scn,与数据块当前所的scn不一致的时候。构造cr块的时候,首先去data buffer中去找包含数据库前镜像的undo块,如果有直接取出构建CR块,这时候是逻辑读,产生逻辑IO;但是data buffer将undo信息写出后,就没有需要的undo信息,就会去undo段找所需要的前镜像的undo信息,这时候从磁盘上读出block到buffer中,这时候产生物理读(物理IO)
4.undo
undo:Oracle在记录undo数据的时候,不仅记录了改变前的数据,还记录了改变前的数据所在的数据块头部的ITL信息(包含scn号)。
undo主要有三大作用:提供一致性读(Consistent Read)、回滚事务(Rollback Transaction)以及实例恢复(Instance Recovery)。
回滚事务则是在执行DML以后,发出rollback命令撤销DML所作的变化。Oracle利用记录在ITL槽里记录的undo 块的地址找到该undo块,然后从中取出变化前的值,并放入数据块中,从而对事务所作的变化进行回滚。
实例恢复则是在SMON进程完成前滚并打开数据库以后发生。SMON进程会去查看undo segment头部(所谓头部就是undo segment里的第一个数据块)记录的事务表(每个事务在使用undo块时,首先要在该undo块所在的undo segment的头部记录一个条目,该条目里记录了该事务相关的信息,其中包括是否提交等),将其中既没有提交也没有回滚,而是在实例崩溃时被异常终止的 事务全部回滚。
5.导致ORA-01555
当sql语句执行查询的时候,当一致读的时候,在构建cr块的时候,undo的SCN号小于等于发出查询时的那个SCN号时。正常来说,当前undo块里记录的SCN号要比上一个undo块里记录的SCN号要小。
但是在查找的过程中,可能会发现当前undo块里记录的ITL槽的SCN号比上一个undo块里记录的SCN号还要大。这种情况说明由于事务被提交或回滚,导致当前找到的undo块里的数据已经被其他事务覆盖了,于是我们无法再找出小于等于发出查询时的那个时间点的SCN号,这时Oracle就会抛出一 个非常经典的错误——ORA-1555,也就是snapshot too old的错误。
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2013-01/77747p2.htm