ORACLE 学习笔记(二)体系结构

ORACLE 体系结构图:
 

 

Oracle 体系结构,包括物理层和逻辑层两大部分。当启动一个oracle实例的时候,就会在内存当中分配一片共享的内存区域(SGA),并启动相应的一些后台进程,这片区域是每个进程之间共享的。另外每个server process 还对应一块Program Global Area (PGA): 包含单个服务器进程或单个后台进程的数据和控制信息,与几个进程共享的SGA 正相反PGA 是只被一个进程使用的区域,PGA 在创建进程时分配在终止进程时回收。

      用户进程(User process):它开始于用户请进连接一个Oracle数据库的时候,它运行于客户端,它并不和Oracle Server直接交互,而是通过Server Process和Oracle Server进行交互。
  服务进程(Server process):连接到一个Oracle实例,并且开始于一个用户session的开始。它和Oracle Server运行于同一台机器上,使用PGA执行User Process发出的调用,并向User Process返回结果状态和结果信息。
  后台进程(Background process)开始于一个Oracle实例的启动。

 

首先说一说SGA:

SGA 的尺寸由下列参数控制:

DB_CACHE_SIZE指定数据库高速缓冲区的大小

LOG_BUFFER指定日志缓冲区的大小

SHARED_POOL_SIZE指定共享池的大小

LARGE_POOL_SIZE指定大池的大小

JAVA_POOL_SIZE 指定java池的大小

但是,SGA的大小尺寸由初始化参数SGA_MAX_SIZE控制

 

在以前版本的oracle数据库中,只能通过修改上述的参数来调整SGA的各个部分,现在Oracle 10g以后引入了SGA自动管理(Automatic Shared Memory Management),DBA只需要对初始化参数SGA_TARGET设置SGA的有效内存,Oracle就会在有效内存内自动对各个内存结构进行调整。

 

(1)share pool:Shared Pool的大小是通过参数SHARED_POOL_SIZE和决定的。它可以分为库缓存(Library cache),数据字典缓存(Data dictionary cache)和用户全局区域(UGA)所组队成的。
  Library cache存放了最近执行的SQL语句、存储过程、函数、解析树以及执行计划等。
  Data dictionary cache存放了在执行SQL语句过程中,所参照的数据字典的信息,包括SQL语句所涉及的表名、表的列、权限信息等。dictionary cache也叫做row cache,因为这里面的信息都是以数据行的形式存放的,而不是以数据块的形式存放的。
  The User Global Area (UGA) 当shared server模式被使用并且Large pool没有被设定的时候这个区域包括用户的session信息。
  oracle对SQL语句进行了概括和抽象,将SQL语句提炼为两部分,一部分是SQL语句的静态部分,也就是SQL语句本身的关键词、所涉及的表名称以及表的列等。另一部分就是SQL语句的动态部分,也就是SQL语句中的值(即表里的数据)。很明显的,整个数据库中所包含的对象数量是有限的,而其中所包含的数据则是无限的。而正是这无限的数据导致了SQL语句的千变万化,也就是说在数据库运行的过程中,发生的所有SQL语句中,静态部分可以认为数量是有限的,而动态部分则是无限的。而实际上,动态部分对解析的影响相比静态部分对解析的影响来说是微乎其微,也就是说通常情况下,对于相同的静态部分的SQL 语句来说,不同的动态部分所产生的解析结果(执行计划)基本都是一样的。这也就为oracle提高解析SQL语句的效率提供了方向。
  oracle会将用户提交来的SQL语句都缓存在内存中。每次处理新的一条SQL语句时,都会先在内存中查看是否有相同的SQL语句。如果相同则可以减少最重要的解析工作(也就是生成执行计划),从而节省了大量的资源;反之,如果没有找到相同的SQL语句,则必须重新从头到尾进行完整的解析过程。这部分存放SQL语句的内存就叫做共享池(shared pool)。当然,shared pool里不仅仅是SQL语句,还包括管理shared pool的内存结构以及执行计划、控制信息等等内存结构。
  当oracle在shared pool中查找相同的SQL语句的过程中,如果SQL语句使用了绑定变量(bind variable),那么就是比较SQL语句的静态部分,前面我们已经知道,静态部分是有限的,很容易就能够缓存在内存里,从而找到相同的SQL语句的概率很高。如果没有使用绑定变量,则就是比较SQL语句的静态部分和动态部分,而动态部分的变化是无限的,因此这样的SQL语句很难被缓存在shared pool里。毕竟内存是有限的,不可能把所有的动态部分都缓存在shared pool里,即便能够缓存,管理这样一个无限大的shared pool也是不可能完成的任务。不使用绑定变量导致的直接结果就是,找到相同的SQL语句的概率很低,导致必须完整的解析SQL语句,也就导致消耗更多的资源。从这里也可以看出,只有我们使用了绑定变量,才真正遵循了oracle引入shared pool的哲学思想,才能够更有效的利用shared pool

 

(2)Database buffer cache:是SGA中的一部分,它存储的是从数据文件中读取的数据块的拷贝,当一个server process访问数据的时候,首先是在buffer cache中查找,如果数据在buffer中存在,我们还需要根据data buffer的状态,来判断是否进行DB Block Gets还是Consistent Gets,如果数据在buffer中不存在,则我们需要在buffer cache中寻找足够的空间来加载我们所需要的数据,如果在buffer cache中我们找不到足够的空间,那么我们就需要触发DBWn进程,去写出脏数据,用来释放我们的buffer空间。
  Oracle通过几个list来对buffer进行管理。其中最主要的是LRU List还有Checkpoint queue,这些list上面存放的就是具体指向buffer的指针。

      LRU List主要就是用来维护内存中的buffer,当数据库初始化的时候,所有的buffer都放入LRU List上进行管理。当我们从数据文件中读取数据的时候我们现在要在LRU List上面寻找free的buffer,然后将数据读取到我们所找到的这个free buffer中,同时搜索dirty block。只要数据被修改了,那么这个buffer的状态就变为了dirty,那么Oracle就会把这个buffer从LRU List移到Checkpoint Queue中去。在Checkpoint Queue上的buffer都是一些候选的稍后会被DBWn写出到数据文件的buffer,那么这里还有一点需要注意的是:一个buffer要么存在于LRU List上面,要么存在于Checkpoint Queue上面,不可能同时存在于两个List上面。(CKPT用来控制数据库文件一致性,以后的日志中还会提到)。

     我们可以通过编辑参数DB_CACHE_SIZE和对buffer Cache进行配置。(不能使用DB_nK_CACHE_SIZE参数来调整标准块的大小。例如,如果DB_BLOCK_SIZE设置为2K,设置DB_2K_CACHE_SIZE。等于2K是无效的。标准缓存的块大小总是由DB_CACHE_SIZE决定的。)指定标准数据库块大小的参数值是4K。标准块大小的缓冲区高速缓存的大小为12M。另外,2K和8K的高速缓存大小分别配置为8M和4M。

    在Buffer Cache中的buffer有四种状态:
  Pinned: The block is either currently being read into the cache or being written to。 Other sessions wait to access the block。(当前正在更新的内存数据块。)
  Clean: The buffer is now unpinned and is a candidate for immediate aging out if the current contents (data block) are not referenced again。 Either the contents are in sync with disk or the buffer contains a CR snapshot of a block。(buffer的内容与数据文件中的一致。)
  Free/unused: The buffer is empty because the instance just started。 This state is very similar to the clean state, except that the buffer has not been used。(buffer cache中的内存数据块为空。)
  Dirty: The buffer is no longer pinned but the contents (data block) have changed and must be flushed to disk by DBWn before it can be aged out。(buffer cache中的内存数据块的内容被修改,从而导致与数据文件中的数据块的内容不一致。)

 

      数据库的管理可以通过建立多种缓冲池(multiple buffer pools)来提高数据的效率。你指定对象到那种缓冲池是根据如何去访问这个对象来决定了。有三种缓冲池:
  Keep: 这个池用来保存对象在内存中以便这个对象被重复使用。保持这些对象在内存中可以减少I/O操作。这个池的大小要比被缓存的数据的总大小要大,所以在这个池中的缓存不会被过期。可以通过修改 DB_KEEP_CACHE_SIZE参数来配置这个池。
  Recycle: 这个池保存在块只有很小的机会会被保存在内存中。这个池的大小要比被缓存的数据的总大小要小,所以被缓存的数据会经常的过期。可以通过修改 DB_RECYCLE_CACHE_SIZE参数来配置这个池。
  Default: 这个池总是存在,它相当于一个buffer cache 的实例不包括Keep和Recycle,可以通过修改DB_CACHE_SIZE参数来配置这个池。

 

(3)Redo Log Buffer: 日志缓冲区是一个可以循环使用的缓冲区。 日志缓冲区存放日志条目(redo entries), 日志条目是有关数据库的改变(INSERT, UPDATE, DELETE, CREATE, ALTER, DROP)。日志条目可以用于数据库的恢复。

      当用户对数据库进行改变的时候,就会产生日志条目,Oracle把日志条目放到日志缓冲区当中。Oracle的后台进程LGWR负责把日志条目写到磁盘上的联机日志文件中。

      初始化参数LOG_BUFFER 用于设置日志缓冲区的大小。比较大的日志缓冲区能够减少联机日志文件的IO。如果一个系统中有比较大的,长时间运行的事务,应该增大LOG_BUFFER。

 

(4)large pool:大池是Oracle可选的内存结构,下面几种情况会用到大池:

             数据库的备份和恢复

             并行查询

             共享服务模式下的会话内存

   如果不创建大池,上面所需要的内存会从shared pool和PGA中进行分配,这样就会降低shared pool的执行性能,所以large pool的内存是和shared pool 分开来的。即相互独立。

 

(5)Background process 一个Oracle database server包括一个Oracle database和一个Oracle instance。一个Oracle实例包括了内存结构,System Global Area (SGA)和后台进程。这些共公的后台进程包括:
System Monitor(SMON):负责数据库崩溃之后的恢复工作,用于维护数据的一致性。他主要完成以下工作:
  1)实例恢复
  2)重做已提交的事务
  3)打开数据库 中国.网管联盟
  4)回滚未提交的事务
  5)合并数据文件中相邻的自由空间
  6)释放临时段的空间
Process Monitor(PMON):当某个进程失效时,清除相关的资源。他主要完成以下工作:
  1)回滚用户的当前事务
  2)释放相关的锁
  3)是否其他相关的资源
Database Writer(DBWn):负责将数据库缓存中标记为修改的块写回磁盘上的数据文件中。他主要完成以下工作:
  1)发生检查点
  2)达到脏缓冲区阈值
  3)没有可用的缓冲区
  4)超时
  5)将表空间设置为脱机或只读
  6)删除或截断表
  7)备份表空间
Checkpoint(CKPT):当检查点产生的数据更新所有的数据文件和控制文件。
  1)使DBWn将SGA中所有被修改的数据库缓冲区的内容写入磁盘,无论事务是否被提交
  2)用检查点信息更新数据文件头
  3)用检查点信息更新控制文件
  他能确保:
  1)将经常被修改的数据块写入磁盘
  2)简化实例恢复
LOG Writer(LGWR)
  LGWR在以下情况将缓冲区中的数据写入磁盘(联机日志文件redo log):
  1)事务提交
  2)三分之一的redo日志缓冲区已满
  3)Redo日志缓冲区中的内容超过1M
  4)每三秒钟
  4)在DBWn写磁盘之前
Archiver(ARCn)
  是个可选的后台进程
  当把数据库设置为ARCHIVELOG模式时,能自动归档联机redo日志
  能够保存所有对数据库所做修改的记录

posted @ 2013-09-02 04:41  rjfrjf1  阅读(234)  评论(0)    收藏  举报