对Oracle体系结构的一些理解

Oracle数据库体系结构中的各个组件的存在的必要性角度来思考,尽量结合实际应用场景,加深对各个组件的理解。

 

客户端与服务端的连接:

Oracle数据库服务是典型的C/S服务模式。

 

1.1 先说客户端:

用户要连接到Oracle数据库库,需要安装Oracle客户端软件,并配置连接信息,之后连接到数据库;对于Java应用,可通过JDBC驱动,并设置连接字符串,通过程序连接到数据库。

 

通过Oracle Client软件连接数据库时,客户端需要知道数据库的主机名(或IP),端口,协议,服务名(或SID)信息,客户端可以采用Local Naming的或Easy Connect等命名方式来设定这些参数信息。

对于Local Naming方式,需要在客户端tnsnames.ora文件中定义tnsname信息;而通过Easy Connect方式时,可直接在连接字符串中体现这些信息,在这个字符串中并未体现连接协议类型,因为Easy Connect方式只支持TCP协议。

  

1.2 再说服务端:

        服务端侦听器进程收到客户端的连接请求后,如果服务模式是Dedicated,则侦听器会启动一个Server Process进程来处理和响应用户的请求,Server Process是连接客户端与Oracle数据的纽带。
        而如果服务模式是Shared,则侦听器会交由Dispatcher进程来接收用户的请求;之后,dispatcher进程将请求交由shared server process来处理,并将shared server process的处理结果返回给用户;(这里还有请求队列和响应队列来辅助该过程)

 

        这里Shared Server模式的适用场景是什么呢?

        当一些联机应用中并发用户数量很大,比如达到了1000,但大多数用户均处于空闲状态的,如果采用Dedicated模式,有如下缺点:

1)需要为每个用户分配一个Service Process以及PGA内存,那么会耗费很大的PGA内存;

2)此外,由于操作系统的CPU时间片算法,大量的Service Process做上下文切换也是不小的开销;
        
        而如果采用Shared Server模式,通过dispatcher将用户的请求进行排队,并交由预先设定一定数量的shared Server Process来处理,这样就缓解了前面出现的问题。但这样做的缺点是单个会话的响应不如Dedicated模式快。
        
此外,11gOracle还提供了DRCP方式来支持大量用户的接入。

 
        
对于J2EE应用,在并发用户量很大的情况下,一般会使用中间件(如WASWebLogic等)提供的数据库连接池来解决该问题。

  

Oracle数据库:

        Oracle数据库指的是数据库的物理结构,包括控制文件、数据文件、重做日志文件,此外还有参数文件、口令文件、归档日志文件。

        数据库的启动以下4种状态的跳转,

1)stopped表明数据库属于停止状态;

2)nomount表明数据库实例已启动;

3)mount表明数据库控制文件已加载;

4)open表示数据库已打开;
 

2.1 参数文件

数据从停止状态启动到nomount状态,需要读取参数文件,从而启动实例。

 

实际测试时,我们只需要提供DB_NAME即可启动实例,说明在不设置参数时,Oracle启用了默认参数值。而如果我们调整了参数的默认值,在数据启动时的alert_.log的日志中,会展示出这些非默认参数值。

        
        
参数文件可分为pfile和spfile两种类型。

其中pfile的内容是文本格式,但是用pfile启动实例后,pfile中的参数不可以被修改,这是一个很大的缺点。而spfile的内容是二进制格式,在实例启动后,可以支持参数的动态修改,但是不容易直接读取,需通过其他方式读取。

 

参数文件放在$ORACLE_HOME/dbs目录下,如果有多个参数文件,Oracle的查找顺序依次是:

spfile.ora

spfile.ora

init.ora

init.ora

 

        按照参数是否可以被修改,以及修改的范围,参数又可以有如下一些类型:

1)  值固定的参数,不可修改;

2)  实例中不可以修改,但可以在spfile中修改的参数,重启方可生效,可通过alter system set … scope=spfile;

3)  可以在实例中生效的参数:

a) 可以在会话级别生效,可通过alter session进行修改;

b) 可以在实例和spfile中同时生效,可通过alter system [deferred] scope=memoryscope=both进行修改的参数;

 

2.2 控制文件

数据库从nomount阶段到mount阶段,需根据control_files参数提供的路径读取控制文件。控制文件中包含了一下一些内容:

 

1)包括数据库的基本信息

例如:每个数据库会生成唯一的ID来标识该数据库;maxlogfiles, maxlogmemebers等参数用于预设值;

 

2)数据库的结构信息,包括数据文件、日志文件、在线日志文件的路径;

数据库在启动时会校验各个数据文件是否一致,如果一致,则表示这些数据文件可以一致性打开;

如果不一致,则需根据控制文件中记录的信息,对数据文件进行恢复。

 

3)包含RMAN备份的元数据(当RMAN不使用Catalog方式时,会使用controlfile

保存);

 

4)包含最后一次检查点的信息;

        记录该信息,当需要实例恢复时,其起点即为该检查点;

 

5)包括归档日志的信息;

记录默认查找的归档信息;

 

6)包含在线日志文件的日志序号;

通过此与日志文件保持同步?还是有其他的SCN信息。

 

        控制文件很重要,因此RMAN有控制文件自动备份的选项,当开启该选项时,当备份数据,或是数据库结构改变时,RMAN均会自动备份控制文件和spfile;此外,当system表空间备份时,无论是否开启该选项,RMAN均会自动备份。

 

2.3 数据文件

数据库从mount阶段到open阶段,需要根据控制文件中提供的数据文件、日志文件等路径,进行校验,通过后打开数据库。

 

数据库open时,会校验数据文件头上的SCN信息,确保各个数据文件是一致的,否则需要根据控制文件中记录的日志信息来进行数据文件的恢复;

数据库还会校验控制文件与数据文件版本是否一致,如果不一致,还需要对数据文件进行media recovery,方可打开。例如:采用备份的控制文件打开数据库时,会发现file1较新,不能打开,可通过recover database做恢复后打开。

 

表空间与数据文件是一对多的关系,数据文件按照所属的表空间,有如下一些类别:

1)system表空间数据文件,存放数据字典、数据库内部使用数据信息;

2)sysaux表空间数据文件,存放收集的快照信息,AWR资料库等;

3)undo表空间数据文件,使用自动undo管理,存放undo数据,用于提供一致性读,提供闪回特性;

4)临时表空间,主要用于磁盘排序;

5)用户表空间,用于存放用户数据,供应用使用;

 

当用户执行一条修改数据的语句时,从磁盘读取该条数据到缓存(或在缓存中已存在),Oracle会构造出undo缓存,存放被修改数据的原值,之后修改缓存中的数据,并将对这些块的修改写入redo log buffer,为了保证可恢复性,redo log buffer需要优先写入日志文件。

       在用户commit时,oracle不强制脏数据块写入磁盘,而是保证将log buffer写入日志文件。一方面强制脏数据块写入,如果该数据块是频繁DML操作的,那么可能会影响数据块的共享,从而增加了磁盘IO;另一方面,日志文件是一种增量顺序的写出,而且redo信息只记录块的变化的内容,所以日志文件是一种批量式的写出。它的效率要高于DBWR离散的写入。

2.4 日志文件

日志文件用于提供数据库的可恢复性。

在日志文件中记录了所有的数据操作,可以看到,当数据库出现故障时,不论是实例故障或是介质故障,均需要通过日志文件来辅助恢复。

 

 在线日志文件至少需要有2组。

一般在一个日志组中添加多个日志成员进行多工,从而保护日志组成员的损坏;此外,考虑将一个日志组的不同成员放在不同的磁盘上,以减少磁盘IO争用。

 

在线日志组文件是增量写入、顺序写入、并且是循环使用的,历史的日志文件被转入归档方便管理。

 

3  Oracle实例:

通过Oracle的实例,用户可以高效的使用Oracle数据库。

Oracle Instance包括内存结构和后台进程。内存结构通过后台进程与Oracle数据库进行交互。

RAC模式下,一个Oracle数据库可以对应多个Oracle实例,从而提供了实例的高可用性。

 3.1 内存结构

内存结构中,有部分组件的数据是可共享的,例如Buffer Cache,第一个会话查询产生的数据块缓存,可供第二个会话来使用;而有一部分缓存是与用户相关的,例如一个会话查询的排序的结果信息、会话、游标等信息,显然不能与另一个会话共享。因此,Oracle将内存结构分为了2大部分,即SGAPGA

 

10g中,SGAPGA可分别实现自动管理;11g中可实现内存的自动管理。

其中,10gSGA中可自动管理的内存组件有Buffer CacheShared PoolLarge PoolJava PoolStream Pool。(不包括非标准大小块的Buffer Cache

SGA_MAX_SIZE参数表示SGA的内存允许调整的最大值;SGA_TARGET表示启动时初始内存值。值得注意的是SGA_TARGET表示的是所有SGA内存组件的大小。

  3.1.1    Database Buffer Cache

数据库中最重要的是数据,这些数据是存放在各种数据文件中的,而这些文件又是存放在磁盘上的。

 

当用户第一次发起业务数据的查询操作时,需要读取磁盘的数据,如果这部分数据不保存在缓存中;那么后续该用户或其他用户继续读取同样的数据时,仍需要从磁盘读取该批数据,这样磁盘的IO就会很高。所以有必要将数据在内存中缓存起来,类似于2-8原则,数据库采用LRU算法,将频繁使用的数据缓存在热端,以减少整体的磁盘IO

我们在创建数据库时,通过DB_BLOCK_SIZE指定了数据库的默认块大小(默认为8K),那么通过DB_CACHE_SIZESGA_TARGET参数可调节默认块缓存区的大小。而对于非标准块,我们可以使用DB_nK_CACHE_SIZE(其中n可取值为2,4,8,16,32)参数来指定非标准块缓存的大小。

  3.1.2    Shared Pool

共享池,它包含Library CacheData Dictionary Cache(又称为row cache),分别用来缓存SQL语句的执行计划,以及数据字典信息。

 

用户提交的SQL语句,在语法校验时需要读取数据字典信息,通过数据字典缓存避免了重复读取system表空间中数据字典表的IO开销;

在解析后会生成执行计划,并保存在库缓存中,由于SQL语句的解析是个耗费CPU的过程,所以通过缓存该SQL的执行计划,在后续提交同样的SQL语句时,可以共享该执行计划,避免CPU开销。

如何匹配以前SQL语句呢,SQL语句会按照一定的规则生成Hash值,通过匹配前面SQLHash值来重用它的执行计划。那么根据应用要求,希望尽量复用原来的SQL的执行计划,那么我们需要按照绑定变量的方式来编写SQL语句。

一般来讲,对于CPU敏感的OLTP应用,要考虑使用绑定变量,提高SQL语句软解析;而对于IO敏感的OLAP应用,不使用绑定变量,以期获取更优的执行计划,从而提高SQL语句的执行效率。

 3.1.3    Redo Log Buffer

当数据库中存在大量DML操作时,可能会生成大量Redo Log;如果不使用缓存,而是直接更新磁盘上的日志文件,必然会存在较长的IO等待以及文件锁定等待;而如果通过redo log buffer,一条DML操作,写入到缓存中后就立即返回,那么会极大的客户端的提高响应速度。

此外,LGWR通过相应的触发机制,近似于实时的速度不断在将redo log buffer中的数据写入redo log file

当然,如果用户执行commit操作,需要同步等待log buffer写入log file

 

         Redo log buffer的块大写一般为操作系统的块大小,以防止出现分裂块。

Log buffer的设置也不宜过大,因为有可能commit时写入缓存数据量较大;

 

3.2     后台进程


待续。



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

转载于:http://blog.itpub.net/9430546/viewspace-1210611/

你可能感兴趣的:(对Oracle体系结构的一些理解)