Oracle9i数据库管理实务讲座(三)
前言 前两期的专栏内容已分别为大家介绍了 Oracle9i for Linux 的安装方式,以及Oracle9i 企业版概观。但是如何组态与管理 Oracle9i 数据库 才是我们要讨论的重点。本文将深入探讨 Oracle9i Instance的组成要素与其运作原理,为您揭开 Oracle9i 的神秘面纱。
前言
前两期的专栏内容已分别为大家介绍了
Oracle9i for
Linux 的安装方式,以及
Oracle9i 企业版概观。但是如何组态与管理 Oracle9i
数据库才是我们要讨论的重点。本文将深入探讨 Oracle9i Instance的组成要素与其运作原理,为您揭开 Oracle9i 的神秘面纱。
本文将涵盖以下主题:
n Oracle9i
服务器架构简介。
n 何谓 Oracle9i Instance
n 系统全域区
n 背景处理程序
在开始任何Oracle9i
数据库管理工作之前,您必须先熟悉 Oracle9i
服务器之整体架构及其运作原理。所以我先为大家简介 Oracle9i
服务器的基本组成架构。
Oracle9i服务器架构
以Oracle9i数据库系统本身而言,大致上可区分为两个主要部分:
n Oracle9i执行个体(Oracle9i Instance)
n Oracle9i数据库档案(Database files)。
简言之,Oracle9i Instance 是指数据库服务器的内存与相关处理程序。您可以想象它就是Oracle9i的心脏。数据库实体则由操作系统内的各式档案组成。如果您想深入了解Oracle9i 系统运作或从事进阶的效能调校,那么一定要搞清楚这两部分彼此的互动关系才行!Oracle9i服务器基本架构如图1所示:
图1:Oracle9i 服务器基本架构。
图1上半部为内存内Oracle9i Instance,下半部则是位于操作系统的各种数据库档案(有关这些档案的细部信息将在下一期说明)。彼此之间是藉由各个背景处理程序互相沟通。
接下来我们先讨论Oracle9i Instance的组成要素。
何谓Oracle9i Instance?
第一次接触Oracle数据库的使用者经常对「Oracle Instance」这个名词感到混淆,因为Instance这个单字从字典上查到的意义跟数据库一点关系也没有!某些中文书译者喜欢将Oracle Instance译为「Oracle实例」,但是我认为这个译名十分不恰当!我个人比较倾向称它为「Oracle执行个体」;俗称「Oracle数据库引擎」。既然是数据库引擎,就表示Oracle数据库内大大小小的事都跟它有关系,当然这也是我们一开始就先讨论的主要原因啰。
Oracle9i 执行个体主要是由以下两项要素组成:
n 系统全域区(System Global Area)
n 背景处理程序(background processes)
来看看什么是「系统全域区」?
系统全域区
当您激活Oracle9i数据库时,系统会先在内存内规划一个固定区域,用来储存每位使用者所需存取的
资料,以及Oracle9i运作时必备的系统信息。我们称此区域为系统全域区(System Global Area),俗称SGA (注1) 。
在 Oracle8i 时,SGA 的大小是由起始参数档(initialization parameter file )内的某些参数所设定。但最麻烦的是每次调整参数之后必须等重新激活数据库才生效(感觉就像在
Windows系统修改了一些设定就要重新开机)。光是数据库的关闭与激活就花去不少时间(难怪大家羡幕 Oracle Consult
ant 很好赚….., just kidding!! ),何况是执行关键性任务的数据库哪能一天到晚开来关去!? 从 Oracle9i 开始,DBA 可以动态配置内存的大小;这样的技术我们称为「dynamic SGA」。有了dynamic SGA ,SGA 的各组成区域都可以动态地进行规划与调整,而不需先关闭数据库。
Tips: 起始参数档(Initialization Parameter file)之意义
如上所述,Oracle Instance被激活时,系统必须藉由某些参数值来配置适当大小的内存空间。换言之,我们可以在激活Instance之前就先规划这些参数的设定值,并储存在操作系统下的某个档案里。往后只要利用此档案就可开启相对应的Oracle Instance — 我们就将这个档案称之为起始参数档。
一般来说,我们还是应该在激活 Oracle9i 之前就妥善规划好适当的内存空间。例如,起始参数档的 SGA_MAX_SIZE(注2)可设定 SGA 所占用的最大内存空间。如果考虑 Oracle9i 的执行效能,理应将此参数尽可能设到最大!但有一点需要注意的是:SGA_MAX_SIZE 尽量不要超过物理内存大小,否则将会使用到硬盘上的虚拟内存,反而导致效能低落。
SGA 的大小可由起始参数档之特定参数所控制,表1整理出与SGA相关的参数名称及其意义:
注1:在多人使用的环境下,SGA 的资料可分享给所有同时上线的联机阶段使用,所以 SGA 有时也称为 Shared Global Area。
注2:如果 SGA_MAX_SIZE 之设定值小于其它 SGA 相关参数设定值的总和;或是小于各相关参数默认值的总和,则 SGA_MAX_SIZE 之设定值无效。
如图1所示,SGA又包含数个重要区域,分别是:
n Database Buffer Cache (资料快取缓冲区)
n Redo Log Buffer (重置日志缓冲区)
n Shared Pool (共享区)
n 其它,如Large pool
以下是每个区域之意义、用途,以及相关设定方式。
资料快取缓冲区
为SGA 的主要成员,用来存放读取自数据文件的资料区块复本,或是使用者曾经处理过的资料。其用途在于有效减少存取资料时造成的磁盘读写动作,进而提升资料存取之效能。所有同时上线的使用者都可以共享此缓冲区的资料。
整个资料快取缓冲区包含两种缓冲区串行,分别是 write list 与
LRU list:
n Write list 存放dirty buffers(注3)之复本,会在适当时机写入磁盘。
n LRU list 包含:free buffers,dirty buffers与pinned buffers。其中free buffer 为空白的缓冲区,随时可存放资料;pinned buffer则是目前使用中的缓冲区。
注3: dirty buffer 是存放”已修改,但尚未写入磁盘的数据”之缓冲区。
资料快取缓冲区运作原理
当使用者第一次向Oracle9i 送出资料查询请求时,Oracle9i 会先在资料快取缓冲区内寻找该资料。如果欲查询的资料恰好已存在于缓冲区内(这样的情况我们称之为 cache hit ),就直接从内存读出资料。
反之,如果缓冲区内并没有使用者欲查询的资料(此情况称为 cache miss ),Oracle9i就会先从磁盘上数据文件读出适当的数据区块,放入缓冲区之后,使用者才从缓冲区读取资料。您可以想象一下:在 “cache hit” 的情况下查询资料的速度是不是比在 ”cache miss” 的情况还快很多呢?事实上,这就是资料快取缓冲区的主要用途所在。
让我们进行更深入的讨论!
当资料区块从磁盘读出,准备放入缓冲区时,系统必须先确定资料快取缓冲区内有free buffers。这时候Oracle9i 会开始扫描 LRU list,扫描的原则为:
n 从 LRU 端扫到 MRU 端
n 当扫描到 free buffer;或是已扫描的缓冲区数目超过临界值时,就会停止扫描动作
n 扫描 LRU list 时如果发现了dirty buffer,就将它移到 write list,然后继续扫描
如果扫描过程顺利在LRU list 内找到 free buffer,那么Oracle9i就会把从磁盘读出的数据区块放入此 free buffer中,然后再把它移到 LRU list 的 MRU 端。
但是,如果 LRU list 真的都没有free buffer怎么办呢?那么Oracle9i 就会停止扫描动作,然后通知数据库写入器(database writer)背景处理程序将部分 dirty buffers 先写入磁盘,接着从 LRU list 的 LRU端开始清除缓冲区。如此一来就可以空出新的free buffer了。
Tips:LRU list 与 LRU 算法
所谓 LRU (least recently used)算法之基本概念为:当内存内剩余可利用的空间不足时,缓冲区尽可能先保留使用者最常使用的资料;换言之,优先清除”较不常使用的资料”,并释放其空间。我以图标方式为大家说明:
我们将 LRU list 想象成是长条型一连串的缓冲区集合,两端点分别为「MRU端」以及「LRU端」。所谓的「MRU」为「Most Recently Used」之缩写,我将之译为”最常使用的”(或是”最近使用的”)。所以,愈靠近MRU端的缓冲区,代表其为被使用者最近查询过的资料。同理,我们将「LRU」端视为”最不常被查询的资料(Least Recently Used)”,或是”很久都没被再次查询的资料”。如下图2中的 State 0 所示:(假设目前LRU list没有任何资料存放)
图2:LRU list第一种使用情况。
图2的State1、State2、State3仿真某个使用者欲从Oracle9i数据库查询出三笔资料(A资料、B资料、C资料)。这三笔数据从磁盘读出后,依序放入LRU list的free buffers。以State3为例:因为C资料是”最近刚刚使用”的资料,所以最靠近MRU端;相较之下,A资料是”有一段时间都没用的资料”,所以比较靠近LRU端。依此类推,如果使用者持续地查询资料或进行相关数据处理动作,则LRU list内的缓冲区都会被填满,如图2的State m所示:M资料填满最后一个free buffer。
如果下一次的查询动作准备再从磁盘读出N资料时存入缓冲区时,LRU list已经没有free buffer可以使用,系统只好清空LRU端存放A资料的缓冲区,接着再放入N资料,结果如图2State n所示。这就是LRU算法的基本运作方式。
让我们讨论另一种情况:
假设在State3之后,恰好有某些使用者持续地查询A资料 — 这会导致A资料一直存放在靠近MRU端的缓冲区。如果M资料被放入LRU list最后一个缓冲区,结果将如图3的State m’ 所示:您会发现图3的State m’ 与图2的State m 有点不同(缓冲区的存放数据完全相同,但存放位置不尽相同)。这时候LRU list内也没有 free buffer了,所以再放入N资料时,系统会清除LRU端存放B资料的缓冲区。不同于第一种情况的是:因为”A资料查询率高于B资料”,所以LRU算法让A资料在缓冲区存放较长的时间,而先移除”较不常使用”的B资料。
图3:LRU list第二种使用情况。
设定资料快取缓冲区之大小
在Oracle9i 设定资料快取缓冲区的方式有别于 Oracle8i 数据库。Oracle8i 的资料快取缓冲区容量由下列公式所决定:
Oracle8i资料快取缓冲区大小 = DB_BLOCK_SIZE * DB_BLOCK_BUFFERS
DB_BLOCK_SIZE:资料区块(data block)之单位大小。DB_BLOCK_BUFFERS :缓冲区数目;每个缓冲区大小相当于一个资料区块之大小。
需注意的是Oracle8i内DB_BLOCK_SIZE在数据库建立之后就不能更改。
然而Oracle9i数据库支持多重区块大小 — 除了预设的DB_BLOCK_SIZE之外,DBA也可以另外设定其它大小的资料区块。因此在Oracle9i数据库中由DB_BLOCK_SIZE所设定的资料区块,我们称为「标准资料区块(standard block)」,其合理的大小可设定在2k – 32k 之间。Oracle9i的起始参数DB_CACHE_SIZE就是设定以”标准区块”所构成的资料快取缓冲区之容量。
重置日志缓冲区
纪录Oracle数据库内所有资料异动的详细信息(例如资料异动前后的新旧资料),我们将这些信息的储存地点称为redo entries。系统也会在适当时机将redo entries内的信息写入磁盘内的档案(注4),以便数据库毁损时可进行必要的复原(Recovery)动作。
注4:由LGWR背景处理程序负责将redo entries写入重置日志文件(Redo log files)。
设定重置日志缓冲区的大小
起始参数档之LOG_BUFFER参数可用来设定此缓冲区的容量,单位为bytes。一般来说,如果重置日志缓冲区的容量较大,可减少日志文件读写动作。重置日志缓冲区的默认值等于操作系统资料区块的四倍。
共享区
当使用者将
SQL指令送至Oracle数据库后,系统将会先解析(parse)语法是否正确。解析时所需要的系统信息,以及解析后的结果(parse tree与execution plan)将放置在共享区内。如果不同的使用者执行了相同的
SQL指令,就可以共享已解析好的parse tree与execution plan,加速SQL指令的执行速度。
共享区之组成
共享区内包含数种不同用途的快取缓冲区,主要可分为两类:
n 函式快取缓冲区(Library cache)
包含:共享SQL区(Shared SQL Area),私有SQL区(Private SQL Area),以及PL/SQL程序单元区。解析完成的parse tree与execution plan就是放在共享SQL区内。
n 数据字典缓冲区(Dictionary cache)。
Oracle9i 在解析SQL叙述句时所需要的系统信息都是放在此缓冲区内,可能包含:资料表(视观表)的名称、字段名称与资料型态;数据库使用者之相关系统管理权限,或是对象存取权限…等。
设定共享区之大小
起始参数档内的SHARED_POOL_SIZE可设定共享区之大小,其默认值大小为8M(注5)。
注5:在32-bit操作系统下,共享区预设大小为8M;如果在64-bit操作系统,共享区预设大小为64M。
背景处理程序
除了SGA之外,系统也会自动激活数个特定的背景处理程序(Background Processes),主要的背景处理程序为:
n DBWn (Database Writer)
负责将资料快取缓冲区内异动过的资料区块回写至硬盘内的数据文件(这个动作又称为checkpoint)。Oracle系统预设只会激活一个DBWn(DBW0)处理程序。但在一般的大型线上交易(OLTP)系统下,数据库异动情况可能十分频繁,您可依实际
需求额外配置其它的Database Writer处理程序(DBW1-DBW9),可以有效地提升Oracle9i写入数据文件之效率!
有一点需要注意的是:在单一处理器的服务器系统,配置额外的DBWn处理程序并无实质帮助。
n LGWR (Log Writer)
在交易被确认时,LGWR会遵循「先期写入协议」,负责将重置日志缓冲区内的资料异动纪录循序写入重置日志文件。
LGWR之动作时机为:
1.当使用者确认(commit)某交易时,LGWR会写入一笔确认纪录。
2. 下列几种情况:
Ø自动周期性地动作,间隔时间为3秒
Ø 重置日志缓冲区之剩余空间不到2/3
Ø 当DBWn回写资料文件时,必要的时候LGWR也会动作
Tips: 何谓「先期写入协议(Write-ahead protocol)」?
在DBWn将dirty buffer回写至资料文件之前,重置日志缓冲区内相关的都必须完成写入动作。如果DBWn发现某些重置纪录尚未写入重置日志文件,它也会通知LGWR前来处理。等到LGWR将重置日志缓冲区的纪录写入完毕时,DBWn才会开始写入资料文件—此即为「先期写入协议」。
n SMON (System Monitor)
如果是因为停电或是其它因素导致Oracle数据库不正常被关闭,下一次激活数据库时将由SMON进行必要的数据库修复动作。其主要工作有:
Ø数据库重新激活后的必要修复动作
Ø 回收不用的暂时性区段(temporary segments)
Ø 收集”字典管理数据表空间”的free extents
Ø 修复交易不正常结束造成的问题
n PMON (Process Monitor)
当某个使用者处理程序异常终止时,PMON会执行「程序修复(process recovery)」动作 — 清除资料快取缓冲区内不再使用的空间,并释放该程序之前使用的系统资源。举例来说,PMON会重新设定transaction table的状态,释放原交易被锁定的资料,然后从程序清单中移除已终止之程序代号(process ID)。
PMON也会定期检查各服务器处理程序以及分配器之状态,如果某个处理程序因故停摆,也是由PMON负责将它重新激活。
n CKPT (Checkpoint)
CKPT会在适当时候产生一个checkpoint事件,其意义为:
1. 确保缓冲区内经常被异动的资料也要定期被写入资料文件。
对于这点,也许大家会觉得非常疑惑。Oracle9i的LRU算法不是会尽量将使用者”最常使用的资料”保留在缓冲区内,以提升资料存取的效率吗?没错,但请大家思考一个问题:如果完全遵循LRU算法的话,DBWn只会将”最不常使用”的资料回写至资料文件,这些”经常被使用”的资料反而没机会存回硬盘!要是数据库当机或毁损,这些资料只能从重置日志文件的纪录才能还原回来,无形中造成系统的额外负担。所以由CKPT掌控checkpoint时机,以确保这些资料照样可被妥善储存。
2. 在checkpoint之后,因为所有更新过的数据已经回写至磁盘数据文件,万一Oracle9i 需要进行instance recovery时,就不再需要checkpoint之前的重置纪录,可缩短数据库重新激活的时间。
此外,checkpoint发生后,CKPT会先通知DBWn将资料快取缓冲区的dirty buffers回写到数据文件,然后更新数据文件与控制文件之checkpoint信息。
n RECO(Recover)
在Oracle9i分布式数据库环境中,RECO处理程序会自动处理分布式交易失败时产生的问题。何谓分布式交易呢?简单的说,就是在同一个交易内针对多个数据库同时进行数据处理动作。与传统资料交易相较之下,分布式交易的要求将严苛许多!因为这些数据库可能分散在
网络上,所以分布式交易的成功与否其中一个关键因素就在于网络传输速度与品质。试想,某个分布式交易需要将资料同时送进5个Oracle9i数据库,此时可能因为网络问题(例如断线或是响应等待时间过长),导致其中一个数据库无法更新这笔交易资料。那么此交易就会发生问题,无法做最后的commit动作;我们将此种交易称为in-doubt transaction。这时候RECO处理程序会自动重新登入包含在分布式交易之各数据库,并尝试进行in-doubt transaction之修复动作。
注6:如果起始参数档DISTRIBUTED_TRANSACTIONS 参数值设定为0,则激活Oracle Instance时不会执行RECO处理程序。
n ARCn(Archiver)
Oracle9i 数据库设定为ARCHIVELOG mode(封存日志模式)时,ARCn处理程序会在 ”log switch” 发生时自动将重置日志文件复制一份到指定的目录下;重置日志文件之副本称为 ”Archived logs” (封存日志文件)。
每个Oracle9i instance最多可激活10个ARCn处理程序(ARC0 to ARC9)。
起始参数档之LOG_ARCHIVE_MAX_PROCESSES 允许您组态ARCn处理程序之个数;或是执行ALTER SYSTEM指令动态地调整。该参数值之默认值为1。事实上,您并不需要设定此参数,因为在封存模式下Oracle9i 会自动判断所需的ARCn个数。一但目前的ARCn处理程序无法负荷时,LGWR会自动激活新的ARCn处理程序。
Tips:何谓Log switch?
当目前的重置日志文件被填满时,LGWR 会切换到下一个可使用的重置日志文件,这个日志文件的切换动作就称为 「log switch」。预设情况下,log switch 会自动发生。
除了以上七个重要的背景处理程序之外,Oracle9i数据库运作时还有其它的背景处理程序互相搭配及运作,例如Job Queue、LMS、QMNn等处理程序。如果您想获取进一步的信息,可参阅OTN网站的《Oracle9i Database Concepts》。
结语
本期内容介绍了Oracle9i的内存结构与其运作原理,下一期我将从数据库与操作系统两个角度深入讨论Oracle9i数据库之实体结构,与常用的数据库对象。
作者简介
何致億,专长为Oracle、
SQL Server 等大型数据库系统管理,资料仓储规划建置,以及数据库应用程序系统
开发。拥有 MCSD、MCDBA,Oracle OCP,RHCE,SCJP,
Borland JBuilder Product Certified等十余项国际认证。目前正致力于Oracle9i应用系统
开发,并负责Oracle9i系列书籍中文化与Oracle Press技术校稿工作。他同时也是美商 Oracle 與 Sun Microsystems公司原厂认证讲师。您可以透过hochihyi@ms64.hinet.net与他联系。
原文转自:http://www.ltesting.net
|