Coundy

   漫步风中,倾听自己的脚步,在自我沉浸中,找寻逝去的灵魂

posts - 27,comments - 2,trackbacks - 0

来自:www.csdn.net

原作者:penitent ( 只取一瓢 ) 

 

在本章里你可以了解以下内容  
  1
、   ORACLE   实例 —— 包括内存结构与后台进程  
  2
、   ORACLE   数据库 —— 物理操作系统文件的集合  
  3
、   了解内存结构的组成  
  4
、   了解后台进程的作用  
  5
、   了解数据库的物理文件  
  6
、   解释各种逻辑结构  

一、 ORACLE 事例  
  1
、 ORACLE   实例  
  System   Global   Area(SGA)  
和   Background   Process   被成为数据库的实例。  
  2
、 ORACLE   数据库  
 
一系列物理文件的集合(数据文件,控制文件,联机日志,参数文件等)  
  3
、系统全局共享区 System   Global   Area(SGA)    
  System   Global   Area  
是一块巨大的共享内存区域,他被看做是 Oracle   数据库的一个大缓冲池,这里的数据可以被 ORACLE 的各个进程共用。其大小可以通过如下语句查看:  
  SQL>   select   *   from   v$sga;  
  NAME   VALUE  
  --------------------   ---------  
  Fixed   Size   39816  
  Variable   Size   259812784  
  Database   Buffers   1.049E+09  
  Redo   Buffers   327680  
 
更详细的信息可以参考 V$sgastat 、 V$buffer_pool  
 
主要包括以下几个部分:  
  a
、   共享池 (Shared   pool)  
 
共享池是 SGA 中最关键的内存片段,特别是在性能和可伸缩性上。一个太小的共享池会扼杀性能,使系统停止,太大的共享池也会有同样的效果,将会消耗大量的 CPU 来管理这个共享池。不正确的使用共享池只会带来灾难。共享池主要又可以分为以下两个部分:  
  ·SQL
语句缓冲 (Library   Cache)  
 
当一个用户提交一个 SQL 语句, Oracle 会将这句 SQL 进行分析 (parse) ,这个过程类似于编译,会耗费相对较多的时间。在分析完这个 SQL , Oracle 会把他的分析结果给保存在 Shared   pool 的 Library   Cache 中,当数据库第二次执行该 SQL 时, Oracle 自动跳过这个分析过程,从而减少了系统运行的时间。这也是为什么第一次运行的 SQL   比第二次运行的 SQL 要慢一点的原因。  
 
下面举例说明 parse 的时间  
  SQL>   select   count(*)   fromscpass   ;  
  COUNT(*)  
  ----------  
  243  
  Elapsed:   00:00:00.08  
 
这是在 Share_pool   和 Data   buffer   都没有数据缓  
 
冲区的情况下所用的时间  
  SQL>   alter   system   flush   SHARED_POOL;  
  System   altered.  
 
清空 Share_pool ,保留 Data   buffer  
  SQL>   select   count(*)   from   scpass   ;  
  COUNT(*)  
  ----------  
  243  
  Elapsed:   00:00:00.02  
  SQL>   select   count(*)   from   scpass   ;  
  COUNT(*)  
  ----------  
  243  
  Elapsed:   00:00:00.00  
 
从两句 SQL   的时间差上可以看出该 SQL   的 Parse   时间约为 00:00:00.02  
 
对于保存在共享池中的 SQL 语句,可以从 V$Sqltext 、 v$Sqlarea 中查询到,对于编程者来说,要尽量提高语句的重用率,减少语句的分析时间。一个设计的差的应用程序可以毁掉整个数据库的 Share   pool ,提高 SQL 语句的重用率必须先养成良好的变成习惯,尽量使用 Bind 变量。  
  ·
数据字典缓冲区 (Data   Dictionary   Cache)  
 
显而易见,数据字典缓冲区是 ORACLE 特地为数据字典准备的一块缓冲池,供 ORACLE 内部使用,没有什么可以说的。  
  b
、块缓冲区高速缓存 (Database   Buffer   Cache)  
 
这些缓冲是对应所有数据文件中的一些被使用到的数据块。让他们能够在内存中进行操作。在这个级别里没有系统文件 , ,户数据文件,临时数据文件,回滚段文件之分。也就是任何文件的数据块都有可能被缓冲。数据库的任何修改都在该缓冲里完成,并由 DBWR 进程将修改后的数据写入磁盘。  
 
这个缓冲区的块基本上在两个不同的列表中管理。一个是块的 “ 脏 ” 表 (Dirty   List) ,需要用数据库块的书写器 (DBWR) 来写入,另外一个是不脏的块的列表 (Free   List) ,一般的情况下,是使用最近最少使用 (Least   Recently   Used,LRU) 算法来管理。  
 
块缓冲区高速缓存又可以细分为以下三个部分( Default   pool,Keep   pool,Recycle   pool )。如果不是人为设置初始化参数 (Init.ora) , ORACLE 将默认为 Default   pool 。  
 
由于操作系统寻址能力的限制,不通过特殊设置,在 32 位的系统上,块缓冲区高速缓存最大可以达到 1.7G ,在 64 位系统上,块缓冲区高速缓存最大可以达到 10G 。  
  c
、重做日志缓冲区 (Redo   log   buffer)  
 
重做日志文件的缓冲区,对数据库的任何修改都按顺序被记录在该缓冲,然后由 LGWR 进程将它写入磁盘。这些修改信息可能是 DML 语句,如 (Insert,Update,Delete) ,或 DDL 语句,如 (Create,Alter,Drop 等 ) 。  
 
重做日志缓冲区的存在是因为内存到内存的操作比较内存到硬盘的速度快很多,所以重作日志缓冲区可以加快数据库的操作速度,但是考虑的数据库的一致性与可恢复性,数据在重做日志缓冲区中的滞留时间不会很长。所以重作日志缓冲区一般都很小,大于 3M 之后的重作日志缓冲区已经没有太大的实际意义。  
  d
、 Java 程序缓冲区 (Java   Pool)  
  Java  
的程序区, Oracle   8I   以后, Oracle   在内核中加入了对 Java 的支持。该程序缓冲区就是为 Java   程序保留的。如果不用 Java 程序没有必要改变该缓冲区的默认大小。  
  e
、大池 (Large   Pool)  
 
大池的得名不是因为大,而是因为它用来分配大块的内存,处理比共享池更大的内存,在 8.0 开始引入。  
 
下面对象使用大池:  
  ·MTS——
在 SGA 的 Large   Pool 中分配 UGA  
  ·
语句的并行查询 (Parallel   Executeion   of   Statements)—— 允许进程间消息缓冲区的分配,用来协调并行查询服务器  
  ·
备份 (Backup)—— 用于 RMAN 磁盘 I/O 缓存  
  4
、后台进程 (Background   process)  
 
后台进程是 Oracle 的程序,用来管理数据库的读写,恢复和监视等工作。 Server   Process 主要是通过他和 user   process 进行联系和沟通,并由他和 user   process 进行数据的交换。在 Unix 机器上, Oracle 后台进程相对于操作系统进程,也就是说,一个 Oracle 后台进程将启动一个操作系统进程;在 Windows 机器上, Oracle 后台进程相对于操作系统线程,打开任务管理器,我们只能看到一个 ORACLE.EXE 的进程,但是通过另外的工具,就可以看到包含在这里进程中的线程。  
 
在 Unix 上可以通过如下方法查看后台进程:  
  ps   –ef   |   grep   ora_  
  #   ps   -ef   |   grep   ora_   |   grep   XCLUAT  
  oracle   29431   1   0   Sep   02   ?   2:02   ora_dbwr_SID  
  oracle   29444   1   0   Sep   02   ?   0:03   ora_ckpt_SID  
  oracle   29448   1   0   Sep   02   ?   2:42   ora_smon_SID  
  oracle   29442   1   0   Sep   02   ?   3:25   ora_lgwr_SID  
  oracle   29427   1   0   Sep   02   ?   0:01   ora_pmon_SID  
  a
、 Oracle 系统有 5   个基本进程他们是  
  DBWR(
数据文件写入进程 )  
  LGWR(
日志文件写入进程 )  
  SMON(
系统监护进程 )  
  PMON(
用户进程监护进程 )  
  CKPT(
检查点进程 , 同步数据文件 ,   日志文件 , 控制文件 )  
  b
、 DBWR  
 
将修改过的数据缓冲区的数据写入对应数据文件  
 
维护系统内的空缓冲区  
 
这里指出几个容易错误的概念 :  
  ·
当一个更新提交后 ,DBWR 把数据写到磁盘并返回给用户提交完成 .  
  ·DBWR
会触发 CKPT   后台进程  
  ·DBWR
不会触发 LGWR   进程  
 
上面的概念都是错误的 .  
  DBWR
是一个很底层的工作进程,他批量的把缓冲区的数据写入磁盘。和任何前台用户的进程几乎没有什么关系,也不受他们的控制。至于 DBWR 会不会触发 LGWR 和 CKPT 进程,我们将在下面几节里讨论。  
  DBWR
工作的主要条件如下  
  ·DBWR  
超时  
  ·
系统中没有多的空缓冲区用来存放数据  
  ·CKPT  
进程触发 DBWR   等  
  c
、 LGWR  
 
将重做日志缓冲区的数据写入重做日志文件, LGWR 是一个必须和前台用户进程通信的进程。当数据被修改的时候,系统会产生一个重做日志并记录在重做日志缓冲区内。这个重做日志可以类似的认为是以下的一个结构 :  
  SCN=000000001000  
 
数据块 ID  
 
对象 ID=0801  
 
数据行 =02  
 
修改后的数据 =0011  
 
提交的时候, LGWR 必须将被修改的数据的重做日志缓冲区内数据写入日志数据文件,然后再通知前台进程提交成功,并由前台进程通知用户。从这点可以看出 LGWR 承担了维护系统数据完整性的任务。  
  LGWR  
工作的主要条件如下  
  ·
用户提交  
  ·
有 1/3   重做日志缓冲区未被写入磁盘  
  ·
有大于 1M   重做日志缓冲区未被写入磁盘  
  ·
超时  
  ·DBWR
需要写入的数据的 SCN 号大于 LGWR   记录的 SCN 号, DBWR   触发 LGWR 写入  
  d
、 SMON  
 
工作主要包含  
        ·
清除临时空间  
        ·
在系统启动时,完成系统实例恢复  
        ·
聚结空闲空间  
        ·
从不可用的文件中恢复事务的活动  
        ·OPS
中失败节点的实例恢复  
        ·
清除 OBJ$ 表  
        ·
缩减回滚段  
        ·
使回滚段脱机  
  e
、 PMON  
 
主要用于清除失效的用户进程,释放用户进程所用的资源。如 PMON 将回滚未提交的工作,释放锁,释放分配给失败进程的 SGA 资源。  
  f
、 CKPT  
 
同步数据文件,日志文件和控制文件,由于 DBWR/LGWR 的工作原理,造成了数据文件,日志文件,控制文件的不一至,这就需要 CKPT 进程来同步。 CKPT 会更新数据文件 / 控制文件的头信息。  
  CKPT
工作的主要条件如下  
  ·
在日志切换的时候  
  ·
数据库用 immediate   ,transaction   ,   normal   选项 shutdown   数据库的时候  
  ·
根据初始话文件 LOG_CHECKPOINT_INTERVAL 、 LOG_CHECKPOINT_TIMEOUT 、 FAST_START_IO_TARGET   的设置的数值来确定  
  ·
用户触发  
 
以下进程的启动需要手工配置  
  g
、 ARCH  
 
当数据库以归档方式运行的时候, Oracle 会启动 ARCH 进程,当重做日志文件被写满时,日志文件进行切换,旧的重做日志文件就被 ARCH 进程复制到一个 / 多个特定的目录 / 远程机器。这些被复制的重做日志文件被叫做归档日志文件。  
  h
、 RECO  
 
负责解决分布事物中的故障。 Oracle 可以连接远程的多个数据库,当由于网络问题,有些事物处于悬而未决的状态。 RECO 进程试图建立与远程服务器的通信,当故障消除后, RECO 进程自动解决所有悬而未决的会话。  
  i
、服务进程 Server   Process  
 
服务进程的分类  
  ·
专用服务进程 (Dedicated   Server   Process)  
 
一个服务进程对应一个用户进程  
  ·
共享服务进程 (MultiTreaded   Server   Process)  
 
一个服务进程对应多个用户进程,轮流为用户进程服务。  
  PGA   &   UGA  
  PGA   =   Process   Global   Area  
  UGA   =   User   Global   Area  
 
他保存了用户的变量、权限、堆栈、排序空间等用户信息,对于专用服务器进程, UGA 在 PGA 中分配。对于多线程进程, UGA 在 Large   pool 中分配。  
  j
、用户进程 User   Process  
 
在客户端,将用户的 SQL   语句传递给服务进程  
  5
、一个贯穿数据库全局的概念 ---- 系统改变号 SCN(System   Change   Number)  
 
系统改变号,一个由系统内部维护的序列号。当系统需要更新的时候自动增加,他是系统中维持数据的一致性和顺序恢复的重要标志。  
  a.  
查询语句不会使 SCN 增加,就算是同时发生的更新,数据库内部对应的 SCN 也是不同的。这样一来就保证了数据恢复时候的顺序。  
  b.  
维持数据的一致性,当一

二、 ORACLE   数据库  
  ORACLE
数据库的组成 —— 物理操作系统文件的集合。主要包括以下几种。  
  1
、控制文件(参数文件 init.ora 记录了控制文件的位置)  
 
控制文件包括如下主要信息  
  ·
数据库的名字,检查点信息,数据库创建的时间戳  
  ·
所有的数据文件,联机日志文件,归档日志文件信息  
  ·
备份信息等  
 
有了这些信息, Oracle 就知道那些文件是数据文件,现在的重做日志文件是哪些,这些都是系统启动和运行的基本条件,所以他是 Oracle 运行的根本。如果没有控制文件系统是不可能启动的。控制文件是非常重要的,一般采用多个镜相复制来保护控制文件,或采用 RAID 来保护控制文件。控制文件的丢失,将使数据库的恢复变的很复杂。  
 
控制文件信息可以从 V$Controlfile 中查询获得  
   
  2
、数据文件(数据文件的详细信息记载在控制文件中)  
 
可以通过如下方式查看数据文件  
  SQL>   select   name   from   v$datafile;  
  NAME  
  ---------------------------------------------  
  /u05/dbf/PROD/system_01.dbf  
  /u06/dbf/PROD/temp_01.dbf  
  /u04/dbf/PROD/users_01.dbf  
  /u09/dbf/PROD/rbs_01.dbf  
  /u06/dbf/PROD/applsys_indx_01.dbf  
  /u05/dbf/PROD/applsys_data_01.dbf  
 
从以上可以看出,数据文件大致可以分为以下几类:  
  i.  
系统数据文件 (system_01.dbf)  
 
存放系统表和数据字典,一般不放用户的数据,但是用户脚本,如过程,函数,包等却是保存在数据字典中的。  
 
名词解释:数据字典  
 
数据字典是一些系统表或视图,他存放系统的信息,他包括数据库版本,数据文件信息,表与索引等段信息,系统的运行状态等各种和系统有关的信息和用户脚本信息。数据库管理员可以通过对数据字典的查询,就可以了解到 Oracle 的运行状态。  
  ii.  
回滚段文件 (rbs_01.dbf)  
 
如果数据库进行对数据的修改,那么就必须使用回滚段,回滚段是用来临时存放修改前的数据 (Before   Image) 。回滚段通常都放在一个单独的表空间上(回滚表空间),避免表空间碎片化,这个表空间包含的数据文件就是回滚数据文件。  
  iii.  
临时数据文件 (temp_01.dbf)  
 
主要存放用户的排序等临时数据,与回滚段相似,临时段也容易引起表空间碎片化,而且没有办法在一个永久表空间上开辟临时段,所以就必须有一个临时表空间,它所包含的数据文件就是临时数据文件,主要用于不能在内存上进行的排序操作。我们必须为用户指定一个临时表空间。  
  iv.  
用户数据文件 (/applsys_data_01.dbf   ,applsys_indx_01.dbf)  
 
存放用户数据,这里列举了两类常见的用户型数据,一般数据和索引数据,一般来说,如果条件许可的话,可以考虑放在不同的磁盘上。  
  3
、重做日志文件(联机重做日志)  
 
用户对数据库进行的任何操作都会记录在重做日志文件。在了解重做日志之前必须了解重做日志的两个概念,重做日志组和重做日志组成员 (Member) ,一个数据库中至少要有两个日志组文件,一组写完后再写另一组,即轮流写。每个日志组中至少有一个日志成员,一个日志组中的多个日志成员是镜相关系,有利于日志文件的保护,因为日志文件的损坏,特别是当前联机日志的损坏,对数据库的影响是巨大的。  
 
联机日志组的交换过程叫做切换,需要特别注意的是,日志切换在一个优化效果不好的数据库中会引起临时的 “ 挂起 ” 。挂起大致有两种情况:  
  ·
在归档情况下,需要归档的日志来不及归档,而联机日志又需要被重新利用  
  ·
检查点事件还没有完成(日志切换引起检查点),而联机日志需要被重新利用  
 
解决这种问题的常用手段是:  
  i.
增加日志组  
  ii.
增大日志文件成员大小  
 
通过 v$log 可以查看日志组, v$logfile 可以查看具体的成员文件。  
  4
、归档日志文件  
  Oracle
可以运行在两种模式之中,归档模式和不归档模式。如果不用归档模式,当然,你就不会有归档日志,但是,你的系统将不会是一个实用系统,特别是不能用于生产系统,因为你可能会丢失数据。但是在归档模式中,为了保存用户的所有修改,在重做日志文件切换后和被覆盖之间系统将他们另外保存成一组连续的文件系列,该文件系列就是归档日志文件。  
 
有人或许会说,归档日志文件占领我大量的硬盘空间,其实,具体想一想,你是愿意浪费一点磁盘空间来保护你的数据,还是愿意丢失你的数据呢?显而义见,我们需要保证我们的数据的安全性。其实,归档并不是一直占领你的磁盘空间,你可以把她备份到磁带上,或则删除上一次完整备份前的所有日志文件。  
  5
、初始化参数文件  
  initSID.ora
或 init.ora 文件,因为版本的不一样,其位置也可能会不一样。在 8i 中,通常位于 $ORACLE_HOME/admin/<SID>/Pfile 下  
 
初始化文件记载了许多数据库的启动参数,如内存,控制文件,进程数等,在数据库启动的时候加载( Nomount 时加载),初始化文件记录了很多重要参数,对数据库的性能影响很大,如果不是很了解,不要轻易乱改写,否则会引起数据库性能下降。  
  6
、其他文件  
  i   .  
密码文件  
 
用于 Oracle   的具有 sysdba 权限用户的认证 .  
  ii.  
日志文件  
  ·
报警日志文件( alert.log 或 alrt<SID>.ora )  
 
记录数据库启动,关闭和一些重要的出错信息。数据库管理员应该经常检查这个文件,并对出现的问题作出即使的反应。你可以通过以下 SQL   找到他的路径 select   value   from   v$PARAMETER   where   name   ='background_dump_dest';  
  ·
后台或用户跟踪文件  
 
系统进程或用户进程出错前写入的信息,一般不可能读懂,可以通过 ORACLE 的 TKPROF 工具转化为可以读懂的格式。对于系统进程产生的跟踪文件与报警日志文件的路径一样,用户跟踪文件的路径,你可以通过以下 SQL 找到他的路径 select   value   from   v$PARAMETER   where   name   ='user_dump_dest';  
   
 
三、 ORACLE 逻辑结构  
  1
、   表空间 (tablespace)  
 
表空间是数据库中的基本逻辑结构,一系列数据文件的集合。一个表空间可以包含多个数据文件,但是一个数据文件只能属于一个表空间。  
  2
、   段 (Segment)  
 
段是对象在数据库中占用的空间,虽然段和数据库对象是一一对应的,但段是从数据库存储的角度来看的。一个段只能属于一个表空间,当然一个表空间可以有多个段。  
 
表空间和数据文件是物理存储上的一对多的关系,表空间和段是逻辑存储上的一对多的关系,段不直接和数据文件发生关系。一个段可以属于多个数据文件,关于段可以指定扩展到哪个数据文件上面。  
 
段基本可以分为以下四种  
  ·
数据段 (Data   Segment)  
  ·
索引段 (Index   Segment)  
  ·
回滚段 (Rollback   Segment)  
  ·
临时段 (Temporary   Segment)  
  3
、区间 (Extent)  
 
关于 Extent 的翻译有多种解释,有的译作扩展,有的译作盘区,我这里通常译为区间。在一个段中可以存在多个区间,区间是为数据一次性预留的一个较大的存储空间,直到那个区间被用满,数据库会继续申请一个新的预留存储空间,即新的区间,一直到段的最大区间数 (Max   Extent) 或没有可用的磁盘空间可以申请。  
 
在 ORACLE8i 以上版本,理论上一个段可以无穷个区间,但是多个区间对 ORACLE 却是有性能影响的, ORACLE 建议把数据分布在尽量少的区间上,以减少 ORACLE 的管理与磁头的移动。  
  4
、 Oracle 数据块 (Block)  
  ORACLE
最基本的存储单位,他是 OS 数据块的整数倍。 ORACLE 的操作都是以块为基本单位,一个区间可以包含多个块(如果区间大小不是块大小的整数倍, ORACLE 实际也扩展到块的整数倍)。  
  5
、基本表空间介绍  
  a.  
系统表空间  
 
主要存放数据字典和内部系统表基表  
 
查看数据数据字典的 SQL  
  select   *   from   dict  
 
查看内部系统表的 SQL  
  select   *   from   v$fixed_view_definition  
  DBA
对系统的系统表中的数据字典必须有一个很深刻的了解,他们必须准备一些基础的 SQL 语句,通过这些 SQL 可以立即了解系统的状况和数据库的状态,这些基本的 SQL 包括  
 
系统的剩余空间  
 
系统的 SGA    
 
状态系统的等待  
 
用户的权限  
 
当前的用户锁  
 
缓冲区的使用状况等  
 
在成为 DBA   的道路上我们不建议你过分的依赖于 OEM/Quest   等优秀的数据库管理工具,因为他们不利于你对数据数据字典的理解, SQL 语句可以完成几乎全部的数据库管理工作。  
 
大量的读少量的写是该表空间的一个显著的特点。  
  b.  
临时表空间 .  
 
临时表空间顾名思义是用来存放临时数据的,例如排序操作的临时空间,他的空间会在下次系统启动的时候全部被释放。  
  c.  
回滚段表空间  
  i.  
回滚段在系统中的作用  
 
当数据库进行更新插入删除等操作的时候,新的数据被更新到原来的数据文件,而旧的数据 (Before   Image) 就被放到回滚段中,如果数据需要回滚,那么可以从回滚段将数据再复制到数据文件中。来完成数据的回滚。在系统恢复的时候,   回滚段可以用来回滚没有被 commit   的数据,解决系统的一直性读。  
             
回滚段在什么情况下都是大量的写,一般是少量读,因此建议把回滚段单独出来放在一个单独的设备(如单独的磁盘或 RAID ),以减少磁盘的 IO 争用。    
  ii.  
回滚段的工作方式  
  ·
一个回滚表空间可以被划分成多个回滚段 .  
  ·
一个回滚段可以保存多个会话的数据 .  
  ·
回滚段是一个圆形的数据模型  
 
假设回滚段由 4   个区间组成,他们的使用顺序就是区间 1à 区间 2à 区间 3à 区间 4à 区间 1 。也就是说,区间是可以循环使用的,当区间 4 到区间 1 的时候,区间 1 里面的会话还没有结束 ,   区间 4 用完后就不能再用区间 1, 这时系统必须分配区间 5 ,来继续为其他会话服务服务。  
 
我们分析一个 Update   语句的完成  
 
① .   用户提交一个 Update   语句  
 
② .   Server   Process   检查内存缓冲 .  
 
如果没有该数据块的缓冲,则从磁盘读入  
  i.  
如果没有内存的有效空间, DBWR 被启动将未写入磁盘的脏缓冲写入磁盘  
  ii.  
如果有有效空间,则读入  
 
③ .   在缓冲内更新数据  
  i.  
申请一个回滚段入口,将旧数据写如回滚段  
  ii.  
加锁并更新数据  
  iii.  
并在同时将修改记录在 Redo   log   buffer 中  
 
④ .   用户提交一个 Commit   语句  
  i.   SCN
增加  
  ii.  
将 Redo   log   buffer   写入 Redo   log   file  
  iii.  
返回用户 Commit   完成  

四、 ORACLE 核心初探  
  1
、 LRU   算法和数据缓冲区  
 
我们知道 Oracle   数据库的文件大小远远大于 Oracle   的所拥有的内存区域 SGA , LRU 就是一种尽可能将常用的数据保留在内存的算法。当数据库需要一个数据缓冲区,他会从数据库缓冲区的 LRU 队列的尾部找一个空闲的缓冲,将一个数据块读入,然后数据库会把这个缓冲区放到 LRU   队列的中部,如果该缓冲被其他程序用到的话,那么他会往队列的头上移动,如果这个缓冲没有被其他程序用到,并且没有被修改过,那么他会慢慢的移动到 LRU   队列的尾部,最终被认为是空缓冲区被其他数据块所覆盖。一旦这个缓冲区被修改过 DBWR 把他从 LRU 队列中移出,放到 LRUW   队列 ( 也叫赃缓冲区 ) 中,等待 DBWR 把他们批量写入数据文件,然后再把他们的缓冲区连接到 LRU 队列的尾部,周而复始的工作。  
 
理解 HASH 算法,为了提高速度 Oracle 在设计中采用了大量的 HASH 算法,这里我们讲一下 HASH 算法的理论知识,在以后的阅读中会对 Oracle 有更好的理解。 HASH 是一种以空间换取时间的做法。假如我有 100 万条数据,以队列的方式存储,如果我要从里面找一条数据,那么我要从头开始找,我所需要的空间是 100 万个存储单元,如果我用 HASH 的方法来存储,我把存储空间划分为 1000*2000 的数组,把 100 万个数据分别按照如下规则添入该数组:  
  1.  
定义一个函数,使得每条数据对应一个 0-999 的值  
  2.  
把该行记录存储在以函数返回值为下标的数组里  
  3.  
我们称该函数为 hash   函数 f(row).   hash   函数的返回值为 hash   值 . 数组为  
  hash  
数组 HashArray[n][m].  
 
即有下列公式  
  find   a   unused   buffer   in   HashArray[f(row)][?]  
  HashArray[f(row)][?]   =   row;  
 
这样,当我们需要一个行时候我们只需简单的计算该行的 hash 值,然后到下标为 hash 值的 hash 数组里找就可以了。即使用最简单的方法也可以很快的找到  
  For   (I=1;I<=2000;   I   ++)  
  If   (HashArray[f(row)][I]   ==   row   )   return;  
  Next  
 
当然 HASH 算法还是很复杂的,这里只是一个最最简单的例子。如果大家有兴趣可以看看有关数据结构的资料 , 这里就不具体展开了。  
   
  2
、 LATCH(Oracle 内部锁 )  
 
有许多人问我 Latch 和 Lock   的区别,其实很简单, Latch 是 Oracle 内部的 Lock ,他负责更为细小的内部读写,比如 Oracle 要把用户更新的数据写入缓冲区,这时候 Oracle 就会在该缓冲区上加上 latch ,用来防止 DBWR 把他写出到磁盘,因为如果没有这个 Latch , DBWR 会把一半新一半老没有用的数据写到磁盘上。  
   
   
 
五、常见问题  
  1
、实例和 SID 的关系是什么?  
 
经常有人问 SID   是什么?在 Oracle   系统中 SID   是一个经常出现的变量,如环境变量 ORACLE_SID ,   初始化文件 initSID.ora ,那究竟什么是 SID   呢?其实 SID   就是 Oracle   实例的标识,不同的 SID   对应不同的内存缓冲 (SGA) 和不同的后台进程。这样一来我们就可以得当在一台物理的服务器上可以有多个 SID   的数据库实例。  
  2
、 Oracle 数据库和实例的关系是什么?  
 
数据库是由物理文件和存取数据文件的实例组成,当存取数据文件的实例是一个的时候,数据库被称做单节点数据库。这是我们看到的最多的数据库形式。当然还有一种多节点数据库,就是一个以上的实例共同访问一个数据库 ( 或者说共同访问一组数据文件 ) ,   更好的提供稳定性和并行处理能力。这在 8i 中被称为 OPS(Oracle   Parallel   Server   ) ,在 Oracle9i   中被称为 RAC(real   application   cluster) 。在这种数据库中。两个 / 多个实例分别在不同服务器上,所有 Oracle   数据文件在共享的磁盘阵列上,多个服务器上的实例可以同时工作,他们通过一个内部的网络进行通信。如果一台服务器不能提供服务的话,另一台会接管它的工作,特别是在关键的业务有很大的潜力。  
  3
、在运行的数据库中数据文件中是不是可能存在没有被提交的数据?  
 
这是可能存在的,因为用户数据文件的数据是由 DBWR 写入的, DBWR 是一个很底层的后台进程,不负责与用户交互。用户的交互是由 LGWR 完成的。  
  4
、在问题 3 中,如果存在没有写入的数据,那么机器突然断电,数据完整性会不会损坏?  
 
不会的,因为数据库的完整性是 LGWR 来保证的,而且 ORACLE 保证了 DBWR 写入数据文件的任何修改已经被记录在重做日志文件中。当系统再次启动的时候,通过读取重做日志文件就可以知道那些数据没有被提交。这时候 ORACLE   会自动回滚那些数据。所以说联机日志的损坏,特别是当前联机日志的损坏,对数据库的影响是巨大的,可能会导致数据库的不完整。  
  5
、数据文件损坏会丢失数据吗?  
 
可以这么说,如果你有备份和归档,就不会。因为所有对数据修改的记录都在重做日志中有记录,所以不会丢失数据,你只要恢复以前的备份再用归档日志文件恢复和当前的在线重做日志就可以恢复所有数据。  
  6
、在线重做日志损坏会丢失数据吗?  
 
以上说了,在线日志对数据库的损坏是极大的,所以不仅可能丢失数据,还可能引起数据库的不同步。在重做日志中的所有 commit 的记录都会丢失,这也是 Oracle   为什么要对在线重做日志文件做镜像的原因。任何的数据丢失都是不允许的。  
  7
、我在事务能不能指定不写回滚段?  
 
不可以的,写回滚段是 ORACLE 保证一致性读和事务一致性的根本。回滚段是高写入段,建议把它放到单独的设备上来。  
 
对于 DDL 语句,如 DROP,TRUNCATE 却可以不写回滚段(没有 UNDO 信息),所以对于整个表的删除,如果数据量比较大,建议用 Truncate   Table 的方法。  
 
不写联机日志也是不可能的,但可以在某些特定操作中,可以写很少的联机日志,如以 NOLOGGING 的方式通过 Create   table   tablename   as   select 创建表,或以 Append 的方式 Insert 数据到表,或直接载入等操作。  
 
六、小结  
 
这里,我们了解了实例和数据库的关系,一个数据库可以有多个实例,但是一个实例却不可能对应多个数据库,在一般的情况下,我们都是用的单节点数据库,即一个实例仅仅对应一个数据库。  
 
我们了解了 ORACLE 实例的组成,包括内存和后台进程,进一步解释了 SGA 的组成与 SGA 的作用,并分析了语句重用的好处。在后台进程中,重要的阐述了 DBWR 与 LGWR ,其中 DBWR 是一个底层的由 ORACLE 控制的后台进程,而 LGWR 负责与用户交互 .  
 
在 ORACLE 数据库中 , 我们重要阐述了数据库的物理与逻辑结构,在物理结构中,需要注意四类以下文件:控制文件,联机日志,数据文件与参数文件。在逻辑结构中,需要清楚每个逻辑结构的关系,从大到小的顺序为:表空间 à 段 à 区间 à 块。  
 
最后,简单的描叙了两个 ORACLE 的核心内容, LRU 算法与 LATCH ,并初步阐述了 HASH 算法的相关内容。有关 ORACLE 更多的核心内容,可以参考相关资料。  

posted on 2006-11-15 15:49 Coundy 阅读(322) 评论(0)  编辑  收藏 所属分类: Oracle

只有注册用户登录后才能发表评论。


网站导航: