读书笔记-高级owi与oracle性能调整-oracle internal

--buffer cache
oracle为了有效管理高速缓冲区,使用hash chain结构.hash chain位于共享池内,使用oracle典型内存结构的管理方法
bucket->chain->header结构.
hash chain位于共享池内,而实际缓冲区信息则位于高速缓冲区.
Oracle使用两种LRU列.LRU列作为最近被使用和未被使用的缓冲区列,包括空闲缓冲区,正使用或已使用缓冲区,未移到LRUW列的脏缓冲区等.LRUW列管理未记录到硬盘的已修改缓冲区列,高速缓冲区上所有缓冲区列一定属于LRU列或LRUW列两者中的一个.
LRU列主列:已使用的缓冲区列,以hot区域和cold区域区分管理.
LRU辅助列:空闲缓冲区列,更准确的表示同是未使用的缓冲区或通过DBWR写入的缓冲区列.
LRUW列主列:已修改的缓冲区列.
LRUW列辅助列:当前通过DBWR写入中的缓冲区列.
oracle 检索空闲缓冲区时,首先在lru列的辅助列上检索空闲缓冲区.若辅助列的缓冲区都被使用,在主列的cold区域检索空闲缓冲区.实例初次启动时,所有缓冲区在辅助列上管理.而且,已修改的缓冲区利用DBWR写入后重新转换成空闲
缓冲区,添加到lru列的辅助列.
lru列和lruw列总是成对出现,这一对列被称作工作组.oracle使用多个工作组,而一个cache buffers lru chain锁存器管理一个工作组.
single block i/o读取的块将插入到mid-point.mid-point的位置是cold区域头部.multi block i/o读取的块将插入到mid-point后移到cold区域的尾部.
检索缓冲区的步骤:
(1)对于用户请求的块DBA和类利用hash函数创建hash值,然后检索hash值相应的hash bucket.
(2)获得保护hash bucket的cache buffers chains锁存器.若是读取工作,就以shared模式获得锁存器;若是修改工作,就以exclusive模式获得锁存器.如果在这个过程中发生争用, 则等待latch:cache buffers chains事件.检索hash bucket上的chain后,确认块相应buffer header存在与否.如果buffer header已经存在,并且相应块已经位于高速缓冲区时,对相应缓冲区以shared模式或exclusive模式获得buffer lock,然后执行所希望的工作.一般情况下,若在获得buffer lock过程中发生争用,则等待buffer busy wait事件.对正在通过dbwr写入的缓冲区,在获得buffer lock的过程中发生争用,则等待write complete waits事件.
(3)若高速缓冲区上不存在块,将先获得管理工作组的cache buffers lur chain锁存器.这个过程如果发生争用,则等待latch:cache buffers lru chains事件.获得锁存器后,在lru列的辅助列上检索空闲缓冲区.若辅助列没有可用的空闲缓冲区,就在主列上按最少使用的顺序检索空闲缓冲区(在此 过程中,如果发现脏缓冲区,则将它移动到lruw列),找到空闲缓冲区后,对于相应缓冲区以exclusive模式获得buffer lock,并从数据文件将块读取到相应的缓冲区.此时,在获得buffer lock过程中若发生争用,则等待read by other session事件.高速缓冲区的正确的物理读取值是从physical reads统计值上减去physical read direct,physical read direct(lob)统计值.
(4)lru列上检索空闲缓冲区时,扫描与_db_block_scan_max_pct(缺省值是40)参数值相同的lru列部份后,若还没有找到空闲 缓冲区,则服务器进程将停止lru列的扫描.服务器进程请求dbwr将脏缓冲区记录到数据文件里,以确保空闲缓冲区.通过dbwr保证拥有空闲缓冲区为 止,服务器进程将等待free buffer waits事件.

--shared pool
共享池在SGA区域上属于变量区域.变量区域由shared pool,java pool,large pool,streams pool组成.
共享池可以再分为多种内存区域,其中具有代表的是library cache和row cache.
共享池中最关键的部份是库高速缓冲区,它是管理与sql语句的执行相关的所有信息的区域.库高速缓存是被kernel generic librarycache管理的,kgl利用kgh分配得到必要的内存chunk.
库高速缓存是hashtable->bucket->chain->handle->object的结构.
oracle 利用应用于对象名称上的hash函数生成的hash值,分配适当的hashbucket,拥有相同hash值的对象通过chain管理.一个 librarycache handle管理一个library cache object.handle对实际lco起到meta信息和指针的作用,lco保存着实际信息.
lco所包含的信息中重要信息如下:
dependency table:当前lco依赖的其它lco的信息.比如sql语句对所参照的表,视图等具有依赖性.
child table:关于当前lco的子lco的信息.如procedure,表这样只赋予了唯一名称的lco不具有子lco,oracle对于 procedure,表这样的对象,总是将方案名存储在一起,所以能保障唯一性.但若是sql语句,将sql文本本身作为名称,所以不能保障唯一性.因此 oracle会创建拥有sql文本名称的父lco,将实际sql cursor信息存储到子lco.如果两个不同的方案a和b,文本虽然相同,但是实际上所参照对象执行不同的sql语句时,oracle将创建sql语句 相应的父lco和方案a执行的sql cursor所对应的子lco,方案b执行的sql cursor所对应的子lco,总共创建三个lco,这时,v$sqlarea,version_count值是3.子lco存储在库高速缓冲的匿名列.
data blocks:lco包含的实际信息所存储的chunk区域的指针信息.如果是sql cursor,sql语句,执行计划,执行文本信息等会被存储到特定内存区域,这些chunk的地址值被lco的data blocks区域管理.
欲检索库高速缓存的所有进程,就必须获得保护相应hash bucket的library cache锁存器.oracle使用的library cache锁存器,其使用数量与大于cpu数量的质数中的最小值相同.
sql的执行:
(1)用户请求执行新sql时,oracle在执行基本语法和权限检查等步骤后,获得hash bucket的library cache锁存器,然后确认库高速缓冲区上是否存在相同的sql,即相同的lco.若在获得library cache锁存器过程中发生争用,则等待latch:library cache事件.存在相同lco存在时直接跳至第8阶段执行,此过程称之为soft parsing.
(2)若不存在相同sql,在获得shared pool锁存器后,从空闲列上查找最适合大小的空闲chunk.如果在获得shared pool锁存器
过程中发生争用,则等待latch:shared pool事件.oracle一直会拥有shared pool锁存器,直到确保chunk为止.
(3)若不存在最适大小的空闲chunk,则查找更大的空闲chunk后分割使用,分割后剩下内存区域重新登记到适当的空闲列.
(4)若检索了所有空闲列也没有找到恰当的空闲chunk,则检索lru列.lru列上的chunk是重建的,而且是当前不使用的.
(5)若在lru列上检索也不能确保适当大小的chunk,则追加分配共享池内的剩余内存空间.
(6)以上过程如果均失败,则发生错误ora-4031.
(7)若找到适当的chunk,对sql相应的handle以exclusive模式获得library cache lock,并创建lco信息.创建lco后,library cache lock变换为null模式,将library cache pin以exclusive模式获得后,创建执行计划.第2~7号过程称为hard parsing.
(8)oracle对sql cursor以shared模式获得library cache lock和library cache pin,并执行sql.这个阶段称为执行阶段.
sql cursor所参考的lco,基本上与sql cursor相同的模式获得library cache lock和library cache pin.但是执行修改对象信息工作时,对相应的对象所对应的lco以exclusive模式获得library cache lock和library cache pin.
(9)oracle对执行结束的sql cursor fetch数据.这个过程就是fetch阶段.在fetch阶段里,sql cursor将library cache lock变换为null模式,并解除library cache pin.

--transaction
用户所执行dml操作在oracle内部按如下顺序进行:
(1)相应事务分配回滚段,这时优先使用当前联机状态的回滚段中一个.回滚段的选择是随机的,若另外的事务正在使用则重试3次,在此过程中失败,则将未联 机的回滚段联机后使用.如果此过程也失败,就会创建新的回滚段,通过这个过程也没有分配到回滚段,使用另外事务使用中的回滚段中用量最少的回滚段.如果服 务器进程在获得回滚段时没有适当的联机状态的回滚段,则等待enq:us-contention事件,直到有适当的联机状态的回滚段为止.
(2)分配回滚段后,在回滚段上创建事务表slot.
(3)创建事务表后会生成txid(transaction id),再将此txid分配给当前事务.txid通过v$transaction视图的xidusn,xidslot,xidsqn表现,这个值指向分给 事务的回滚段头上存在的事务表的准确位置.事务必须在分配撤销区后得到txid.
(4)事务对象的数据块加载到高速缓冲区,在块头的itl(interested transaction list)上登记事务条目(transaction entry).如果itl上没有登记条目所需的空间,直到有空间为止,一直等待enq:tx-allocate itl entry事件.
(5)按需要修改的块的修改信息存储到pga,存储名为change vector.修改一行时,一般分别创建撤销头块(change vector#1),撤销块(change vetcor#2),数据块(change vector#3)相应的change vector.进程将pga的change vector以名为redo record(或redo entry)复制到重做缓冲区.在复制到重做缓冲区的过程中,需获得redo copy锁存器,redo allocation锁存器,redo writing锁存器,在此过程中若发生锁存器争用,分别等待latch:redo copy,latch:redo allocation,latch:redo writing事件.
(6)将之前映像信息(before image)记录到撤销块,继而修改数据块,被修改的数据块变为脏状态.而且,高速缓冲区上创建关于已修改的数据块的cr(consistent read)块.如果需修改的行正在被另外事务所改变,就要等待事务结束,此时会等待enq:tx-row lock
contention事件.
(7)执行提交后给事务分配scn,提交信息存储在重做缓冲区.
(8)回滚段头的事务表中存储已成功提交的信息,解除包括tx锁在内的所有资源占有.
(9)重做缓冲区的内容记录在重做日志文件上,修改的块之后被dbwr记录到数据文件中.

--segments
oracle并没有全部使用通过区新分配的所有空间实际上,所以需要区分已用空间和未用空间的标志,这个标志就称为高水位线(hwm).
oracle提供的段空间管理方法分为flm(手动管理)和assm(自动管理).表空间创建时赋予的segment space management属性决定flm
和assm的使用与否.
手动模式的空间管理一般称为flm.使用flm时,oracle利用空闲列方法管理段空间.空闲列就是linked list形式管理空闲块的方法.段头块上管理空闲列的头和尾的位置.个别数据块上具有块是否存在于空闲列和下一个空闲块的位置信息,这些信息的组合构成了 空闲列.使用flm时判断空闲块与否,取决于创建表时赋予的pctfree和fctused属性.oracle给每个段基本上分配一个主空闲列,创建几个 进程空闲列,数量与创建段时freelists属性值相同.如果freelist属性值赋予1(1为缺省值),则主空闲列起到进程空闲列的作用.
使用assm后就不有必要指定空闲列属性,各块的状态是通过位图值管理的,从而实现空间管理的自动化.assm对一个段管理两个hwm.
low hwm以下的块保证都是已格式化的状态;high hwm以上的块都是未格式化的状态.lhwm和hhwm之间的块部份被格式化,部份没有格式化.使用assm基本上是通过oracle管理段空间的,所以 从根本上杜绝了dba因赋予错误的storage属性而引起性能问题的可能性.而且,块自然地被分散,所以不会出现flm上的空闲列争用之类的性能问题.

--i/o
i/o性能问题的原因和寻找解决方法的过程:
(1)应用程序层:select,insert,update,delete,truncate...
oracle提供了多种有效i/o处理的方法.其中,parallel query,parallel dml,nologging,direct load,direct read就是最具代表性的例子.根据数据性质,恰当使用cluster,iot,partitioning,bitmap index等功能,有效使用i/o也是应用程序所要承担的任务.
(2)oracle 内存层:buffer cache|pga
a.提供touch count为基础的有效的lru算法.
b.通过buffer pinning方法,减少不必要的锁存器争用,使得当前读取工作中使用概率高的块不至于从内存中挤出.
c.利用多重缓冲池功能,区分临时性块和内存常驻块进行有效管理.
d.利用不同的块大小.
e.处理没必要存于内存的大量数据时,可以使用direct path i/o
(3)oracle 段层:datafile,tempfile,tablespace,segment使用临时表空间.合理使用oracle 8i开始提供的lmt和oracle 9i起提供的assm,可解决因区及段空间的不当管理引发的大部份性能
问题.
(4)os/裸设备层:asynch i/o,direct i/o,raw device,raid...
oracle建议尽量使用异步i/o.异步i/o不仅在读取工作中执行,而且在执行dbwr或lgwr等写入工作的进程上也可以异步地处理工作,因而从整 体上改善了i/o工作的速度.若不能使用异步i/o,应该使用os级的direct i/o.使用多个dbwr进程也可成为一种方法.

--redo
创建重做数据的原因是为了恢复.oracle通过write ahead rule和log force at commit两种机制保障数据的恢复.write ahead rule表示在修改数据之前必须创建重做.将dml引起的变化存于高速缓冲区之前,事先存到重做缓冲区.log force at commit表示用户请求提交后,必须将相关的所有重做记录存于日志文件才能使提交结束.通过这两种机制,oracle保障用户修改的所有数据能成功地存 储在数据重做区域,发生实例故障时能从重做日志文件恢复数据.
重做区域上存储四种区域的修改数据:撤销段头,撤销块,数据段头,数据块.
重做缓冲区的内容会以显式或隐式的记录到重做日志上,LGWR满足如下条件,将做缓冲区内容存于重做日志上:
(1)每隔3秒
(2)达到重做缓冲区的1/3或1mb时
(3)用户执行提交或回滚时
(4)dbwr向lgwr请求写入工作时(write ahead rule)

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28539951/viewspace-1264947/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/28539951/viewspace-1264947/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值