Oracle笔记----1 体系架构

学习Oracle也大半年了,有些知识是反反复复的在看,现在也想把自己的学习过程记录下来也好对不足的地方加以总结。


这个第一帖就从体系架构开始吧:)~

 Oracle的整个体系架构是物理和逻辑两块组成,物理上的是指磁盘上的数据文件,日志文件,控制文件以及物理内存。
逻辑上的是指运行在后台的一组进程。
Oracle的官方资料则是把Oracle分为  Oracle数据库和Oracle实例, 数据库就是指存放在物理磁盘上的数据文件,日志文件和控制文件。   数据库实例则是由一部分共享的内存和一组Oracle的后台进程组成的。数据库实例负责对数据库进行存储,修改。所有的客户端要与数据库进行通信,必须经过数据库实例。

先不谈后台进程,来谈谈内存。 Oracle的内存是由操作系统分配给Oracle的,分为SGA和PGA,其中SGA是系统全局区,只有一个,是共享的,而PGA则是程序全局区,是由许多个小的PGA所组成的,是非共享的,在不同版本的concepts中,还把PGA细分为PGA+UGA,在专有模式下,UGA就在PGA中,而在共享模式下,UGA则是属于SGA。

先来讨论SGA:
SGA一般分为以下几个大的部分:
共享池(shared_pool)-----数据缓冲区(buffer_cache)------重做日志缓冲区(rebo buffer)-------JAVA池(java pool)--------大池(lagre pool)

顾名思义,JAVA池是存放跟JAVA程式有关的一些东西,我们不必去深入研究。
而大池就目前我学到的来说,是会存放RMAN的一些信息,在共享模式下,UGA也会存放在大池中,这个内存还是很重要的。

PGA与UGA的关系有些类似进程与会话的关系,一般情况下是1对1,但也有特殊情况是一个进程对应多个会话。


下面来说下SGA几个比较重要的内存区域:
共享池(shared_pool) :这个区域是用来存放sql语句,执行计划以及数据字典的,当某用户通过客户端进程连接上服务器进程,然后分配到一个PGA后,执行一个SQL语句,首先在PGA中对此SQL语句进行HASH运算,生成一个值,然后通过这个值在共享池的库缓存中申请对应HASH值的bucket的latch,用以查看是否有此语句的执行计划存在,如果有,在该执行计划的句丙上加上一个library cache lock,然后通过句丙所指向的地址找到执行计划,在执行计划所在的内存上加一个library cache pin,用于防止在执行的过程中该执行计划被移出内存了。

当用户在执行一个sql语句时,要进行语法分析,语义分析,其中语法分析是检查sql语句的格式是否正确,语义分析是检查所访问的对象是否存在,或者是否有权限。
语义分析阶段就要借助Oracle的数据字典了,因为数据字典里面存放着各个用户以及各个对象的信息,哪些对象存在,以及相应的权限记录信息都在 Directory 中。在需要的时候,Oracle会先从磁盘中把对应的数据字典读入 Directory cache中,然后再从directory cache中读取相应的数据进行检查。

在进行了语法分析和语义分析之后,Oracle就认为这是一个正确的SQL语句,从而就会对其进行HASH运算,生成一个HASH值,这3步都是在PGA中进行的,通过此HASH值,再去library cache中查找是否有对应的执行计划存在,如果有则直接执行,这个即是软解析。  如果没有该执行计划存在,则此进程会先释放掉library cache latch,来申请shared pool latch 来查找free list,找到一段适合的内存,然后重新申请library cache latch,在此latch所对应的bucket链上生成一个新的节点,该节点指向刚刚所申请的内存,用以存放执行计划。  然后调用CPU在PGA中生成执行计划,再把执行计划从PGA中 COPY到 library cache中, 这个过程即是硬解析。

硬解析会耗费很大的资源,特别在繁忙的数据库中,因为在生成执行计划的过程中,该进程会一直持有library cache latch,这样会造成 latch free的等待时间,而且硬解析还会耗费大量的CPU资源,造成其他的动作变慢,所以一个好的库,尽量减少硬解析的可能,这点可以通过帮定变量以及设置解析的参数来实现。
查看当前数据库中的游标共享模式:
show parameter cursor_sharing
一共有3种:
force: 强制执行方式不同,但是意思相同的语句共享一个执行计划。
similar:在有统计信息的情况下,使用exact模式,没有则使用force模式。
exact:只有完全一致的语句才共用一个执行计划。

Oracle建议采用 similar模式。


说完shared_pool下面来说说buffer_cache。
buffer_cache,顾名思义,是用来存放从数据文件中读入的数据块的,Oracle所有的操作都是在内存中进行的,然后在适当的时候再写入磁盘,因为物理的IO是一个很大的开销相比内存操作,所以当用户需求的数据在内存中找不到时,会由CPU(这里有点模糊,因为写是DBWR进程)读入该数据进内存,当然这个过程也涉及到几个latch的申请和相应的等待时间,我在以后再做详细描述。  反正,现在只需要知道buffer_cache存放的就是数据,其对应物理磁盘上的数据文件中的数据块,在修改一个数据块后,在某个特定的时间段由DBWR进程写入对应的数据块,比如 数据文件号,块号。  数据块是Oracle中最小的数据单位,一个数据块包含一行或多行数据,所以在对某一行数据进行修改的时候,会把这行所在的数据块整个读入内存,加锁进行修改,所以如果单个块出现争用,那么就加大此块的pctfree值,使得一个块里面所存放的行记录减少,从而降低争用的几率:)。
cache里面有两个比较重要的链, LRU 链和dirty 链,buffer_cache中所有的数据块不是在LRU上就是在dirty 上,LRU链用来管理free 内存块,而dirty链则用来管理修改过的脏块,通过这2个链,再结合 cache buffer chain latch,从而形成了cache buffer的管理机制,这个会在latch的笔记中作详细的说明。

最后是关于log buffer.
这部分内存也是至关重要的,用户对数据库的DML,DDL操作都会被记录下来,用于数据库崩溃或者异常关机之后的恢复,而log buffer则对应磁盘上的 log文件,一般由于log文件读写频繁,所以要放在RAW设备中,而且用RAID0的格式。
log buffer写的条件:
1.每3秒
2.达到1M
3. 1/3满
4.  用户commit


以上几个条件任意一种都会发生写操作,由此可见log buffer操作之频繁,所以这部分设备的好坏对于数据库的影响至关重要,切记切记。




好了,以上就是Oracle体系架构中有关Oracle实例的部分了,这个也是Oracle的核心。






































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

转载于:http://blog.itpub.net/22166274/viewspace-664580/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值