ORACLE 体系结构

Oracle体系结构如图:

wpsDCA0.tmp

      一般情况下是一个实例instance和一个database组成。实际生产很多实用到RAC技术,就是一个数据库对应多个实例。

    Oracle实例:实例是指操作系统中一系列的进程和进程所分配的内存块。通俗的说,实例是访问数据库文件的通道。

    数据库是通过数据库实例来访问的,数据库实例由SGA(SYSTEM GLOBAL AREA)和PGA(前台进程,一个用户连接一般对应一个PGA),8大后台进程组成。

一、PGA

   用户进程对应应用服务器的连接,oracle数据库为每一个用户进程分配一个服务器进程(PGA)来处理该连接。

   PGA(程序全局区)为每个服务进程私有的内存区域,程序全局区主要包含排序区、会话区、堆栈区和游标区四个部分的内容:

(1)堆栈区

    保存绑定变量、会话变量、SQL语句运行时的内存结构等重要的信息。

(2)游标区

     当使用游标时,会在游标区分配一块区域,当关闭游标时,会释放。  但是频繁创建和释放,需要耗费系统资源,降低语句的执行性能。

     Oralce通过限制游标的数量来提高数据库的性能。数据库系统中有一个初始化参数OPEN_CURSORS。管理员可以根据实际的需要,来设置这个参数,控制用户能够同时打开游标的数目。

    ora-01000: 超出打开游标的最大数。在java代码中,执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭。

   如果你不使用连接池,那么就没有什么问题,一旦Connection关闭,数据库物理连接就被释放,所有相关Java资源也可以被GC回收了。
但是如果你使用连接池,那么请注意,Connection关闭并不是物理关闭,只是归还连接池,所以PreparedStatementResultSet都被持有,并且实际占用相关的数据库的游标资源,在这种情况下,只要长期运行,往往就会报“游标超出数据库允许的最大值”的错误,导致程序无法正常访问数据库。

      一般来说,写Java代码的时候,createStatement和prepareStatement都应该要放在循环外面,而且使用了这些Statment后,及时关闭。最好是在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statment关闭,调用close()方法。

(3)排序区

A、基于操作符的排序,group by、order by、rollup和窗口函数

B、hash散列连接

C、位图合并、位图创建

(4)会话区

     这个会话区内保存了会话所具有的权限、角色、性能统计等信息。这个会话区一般都是由数据库进行自我维护的,系统管理员不用干预。

二、SGA

     SGA(System Global Area)系统全局区,对系统内的所有进程都是共享的。当多个用户同时连接到一个例程时,所有的用户进程、服务进程都可以共享使用这个SGA区。各种数据库的操作主要就是在这个SGA区内完成。

1、Buffer Cache

     数据库的数据缓存,oracle将数据文件的信息缓存在此区间。Buffer Cache的命中率等,直接影响数据库的性能。

2、Redo Log

     如果数据需要写到在线重做日志中,则在写至磁盘之前要在重做缓冲区(redo buffer)中临时缓存这些数据。由于内存到内存的传输比内存到磁盘的传输快得多,因此使用重做日志缓冲区可以加快数据库的操作。如果没有这个区,那操作一次数据库就访问一次磁盘,而如果有的话,则可以操作很多次之后才访问一次磁盘。速度当然要快很多了。

3、Shared Pool

      Shared Pool主要由两部分组成,一部分是库缓存(Library Cahce),另一部分是数据字典缓存(Data Dictionary Cache),在ORACLE中也叫ROW Cache。

      Library Cache主要用于存储SQL语句、SQL语句相关的解析树、执行计划、PL/SQL程序块(包括匿名程序块、存储过程、包、函数等)以及它们转换后能够被Oracle执行的代码等,字典缓存的内容是按行(Row)存储的(其他数据通常按Buffer存储),所以又被称为Row Cache。

4、large pool

     在Oracle 8.0引入大池之前,所有内存分配都在共享池中进行。如果你使用的特性要利用“大块的”内存分配(如共享服务器UGA内存分配),倘若都在共享池中分配就不太好。另外,与共享池管理内存的方式相比,处理(需要大量内存分配)会以不同的方式使用内存,所以这个问题变得更加复杂。共享池根据LRU来管理内存,这对于缓存和重用数据很合适。不过,大块内存分配则是得到一块内存后加以使用,然后就到此为止,没有必要缓存这个内存。

二、后台进程

     oracle中的进程共分为三类:用户进程、服务进程、后台进程。其中后台进程伴随实例的启动而启动,他们主要是维护数据库的稳定,相当于一个企业中的管理者及内部服务人员。他们并不会直接给用户提供服务。

1、DB Writer:将Buffer Cache中的数据写入数据文件。

   触发条件:(1)检查点(2)一个服务进程在设定的时间内没有找到空闲块(3)每三秒自动唤醒一次。

2、Log Writer:将Log Buffer中的数据写入Redo Log中。

       触发条件:(1)用户发出commit命令。(2)三秒定时唤醒。(3)log buffer超过1/3,或日志数量超过1M。(4)DBWR进程触发:DBWn视图将脏数据块写入磁盘先检测他的相关redo记录是否写入联机日志文件,如果没有就通知LGWR进程。

3、Check Point维护数据库一致性状态。检测点时刻数据文件与SGA中的内容一致,这不是一个单独的进程,要和前两个进程一起工作呦。DBWR写入脏数据,同时触发LGWR进程。

4、Process Monitor: 发现用户进程异常终止,并进行清理。释放占用资源。

5、System Monitor:(1)负责实例恢复,前滚(Roll Forward)恢复到实例关闭的状态,使用最后一次检查点后的日志进程重做。这时包括提交和未提交的事务。打开数据库,进行回滚(Roll Back):回滚未提交的事务。(oracle承诺commit之后数据不会丢失,现在我们可以大致的了解是如何实现这个承诺,以及在数据的安全性和数据库性能之间的平衡选择。)(2)负责清理临时段,以释放空间。

此章只对知识点进行简单的介绍,具体细节,专门章节介绍。

原文地址:https://www.cnblogs.com/ironyoda/p/5627310.html