RAC
在Grid Infrastructure安装完以后,我们把注意力转移到集群上的Oracle软件的安装上来。我们看到,Grid Infrasctructure提供了运行RAC的框架,包括集群通讯链接、节点分离、节点成员关系等服务。ASM是Oracle存储数据库的首选方式。RAC利用这些概念并扩展了需要的基本服务。
安装选项
成功安装了Grid Infrastructure/Clusterware以后,Oracle Universal Installer检测到集群环境的建立,然后提供安装整个集群上或是用户指定其中几个节点的RAC选项。使用集群检验工具cluvfy来为RDBMS的安装检测是否满足先决条件是良好的做法。和安装集群一样,Oracle Universal Installer将首先在第一个节点上对软件进行拷贝和链接,然后将Oracle主目录push到指定的其他节点中。和Grid Infrastructure不同的是,Oracle RDBMS可以被安装在共享文件系统上(例如OCFS2或ACFS上),在集群中增加新节点被简化,因为不需要在新的节点上重新安装软件,打补丁同样被简化了--只有一个Oracle主目录需要打补丁。但是补丁不能以rolling方式安装,因此停机时间不可避免。
在安装过程中,Oracle Universal Installer将提醒管理员安装或升级数据库,或只安装软件。如果安装的时候有新的版本发布,那么仅仅安装软件,打补丁升级后再创建数据库是比较好的做法。
单实例和RAC数据库
RAC和单实例数据库在很多重要方面都有所不同。
在RAC中,一个数据库在共享存储中为多个服务器上的实例所访问。数据库文件、在线redo文件、控制文件和服务器参数文件(spfile)都必须共享。此外,闪回日志、已归档的redo日志、数据泵转储文件、和dataguard broker配置文件也可以共享,根据你的配置来决定(这是可选的,但还是强烈建议这么做)。在使用ASM的时候,你同样可以在每个RAC的节点中找到一个本地的pfile文件,这个文件指向对应磁盘组中的spfile。另一个存储在本地的文件是Oracle密码文件。集群文件系统中的用户常常把这些文件放在一个共享的位置,通过符号链接指向$ORACLE_HOME/dbs
数据库文件
数据库文件包含数据库中的所有数据,包括表、索引、数据字典和经过编译的PL/SQL代码,不胜枚举。在RAC中,每个数据文件都只有一个拷贝,位于共享存储中,并为所有实例所访问。Oracle默认不为数据文件提供镜像,大部分用户选择在存储层面来做冗余,避免介质故障导致的数据丢失。在存储阵列没有这个功能时,可以使用Oracle ASM来提供冗余。
控制文件
控制文件储存数据库的物理结构的相关信息,包括它们的状态。如果你使用RMAN且没有专门的RMAN catalog数据库,控制文件中也可以储存RMAN备份的信息。在单实例数据库和RAC中,控制文件应该做镜像以防止损坏或存储故障。当同时使用ASM和闪回恢复区时,会自动做多路复用。默认情况下,Oracle在db_create_file_dest和db_recovery_file_dest指定的磁盘组中对控制文件做多路复用。这种情况下,若你使用spfile,control_files参数将自动更新。要知道控制文件会成为RAC中的一个争用点,因为它们会被频繁更新。因此不要对控制文件做过多的镜像拷贝,而且应该把它们放置在高速存储上。
REDO和归档
在RAC中,每个实例有它自己的联机日志文件,称为线程(thread)。线程的信息可以在V$LOG和相关的视图中查看。
每个线程中你需要两组redo日志,而且若没有使用ASM和闪回恢复区,你应该考虑手动对组中的成员做多路复用。由spfile负责实例和线程间的映射(通过初始化参数thread)。当添加一个新的实例到集群中时,就需要一个相应的redo线程,这可以使用两种方式来做到:第一种,执行SQL语句alter database add logfile group x thread y; 第二种,在使用策略管理的数据库(policy-managed)中,会自动创建。然后由Oracle来启用。
lgwr后台进程将redo buffer刷新到redo log中。online redo log需要放在高速存储中,否则它可能会成为一个争用的点,特别是在一个高频率提交的系统中。通常对设计不合理的应用的优化是减少commit的频率,并至少将redo log和控制文件移到高速存储中,以减少一些性能瓶颈。在日志切换频繁的系统中,增加每个线程的重做日志组数会有所帮助,它能给归档进程更多的时间来归档redo日志。这种方法在归档进程需要将归档的redo传送到standby数据库中时也能获益,但是,现在的大部分系统采用Log Network Service(LNSn)进程来异步传送redo给standby数据库的Remote File Server(RFS)进程。在Oracle 10.2和11.1中,每个destination有一个LNS进程,到了11.2,LNSn进程被NSSn何NSAn后台进程所代替。NSSn进程被用来同步传送redo,NSAn用来异步传送redo。redo log大小设置的原则是,日志切换不会太频繁(AWR和statspack能够帮助定义一个合适的大小)。Oracle 11.2还允许管理员来选择redo log的块大小,现代存储单元使用4kb扇区大小代替了原先的512b。
当RAC中的一个实例发生故障,所有线程被合并来帮助建立恢复集,由服务器监控进程来执行前滚或回滚操作。
在lgwr进程将一个redo log写满以后,其中一个归档进程会将该文件拷贝到指定的目录中。
闪回恢复区在Oracle 10.1中引入,看是来是归档日志的最佳存放位置。如果你没有使用闪回恢复区,建议将归档日志放在一个共享文件系统中,以便每个节点都可以访问到。与单实例数据库不同,RAC需要所有线程的归档日志。当一个实例执行介质恢复时,你可以从它的alter日志上看到,Oracle使用了每个线程的所有日志文件。
Undo表空间
和redo线程类似,每个集群数据库的实例由它自己的undo表空间。spfile中配置了实例和undo表空间之间的一对一映射关系。但这个映射并不代表该undo表空间就长期绑定在该实例上,所有的其他实例同样可以访问该undo表空间来创建块的读一致前镜像。
当添加一个实例到集群中时,需要添加新的undo表空间并映射到该实例,和redo log一样。在policy-managed数据库中,Oracle可以自己来做这件事。
虽然还是可以使用手动的undo管理,但是强烈建议使用自动undo管理(AUM)。
RAC数据库的存储选项
管理员可以在如下的选项中选择:
- ASM 这是Oracle的首选存储选项,而且是RAC标准版中支持的唯一配置
- OCFS2
- 裸设备 不推荐使用,不仅是因为被新版的linux内核弃用,在Oracle 11.2中同样不支持
- 网络文件系统(NFS)
- Red Hat Global File System 只在红帽和Oracle Enterprise Linux中支持,可以用在闪回恢复区和数据库文件上
RAC实例
一个RAC数据库包含2个或更多的实例,一般每个实例都在不同的节点上,由一些共享内存结构和后台进程组成。
每个实例都有自己的SGA,在实例启动的时候分配。Oracle在10g中引入了自动共享内存管理(ASMM),在11g中引入了自动内存管理(AMM)。但是AMM与linux的大页面不兼容,这对大内存的系统来说是个问题。
Oracle需要同步访问本地共享内存和整个集群。所有实例都能访问其他实例的SGA。
在RAC中Oracle内核对共享内存的保护措施和单实例中是一样的,同样使用了闩和锁。闩是一个低级别、轻量级的串行装置。请求闩的进程不会排队,如果进程不能获得闩,它就会进入spin状态。spin的意思是,这个进程会进入一个紧密循环来预防被操作系统的调度程序从CPU中取下。如果一个进程长时间得不到闩,它会进入睡眠,在一个时间间隔后再次尝试申请。闩是实例级别的,没有集群范围的闩。
另一方面,锁在更长的时间请求一次,比闩更为复杂。锁可以是共享或独占的,请求锁的进程以先进先出(FIFO)的机制来等待,由队列来控制锁的访问,这个队列是集群范围内的。
缓存一致性的需求意味着锁和闩在RAC中比单实例要更加复杂。和单实例中一样,对buffer cache中数据库的访问和队列必须在本地实例中管理,但是,远程实例的访问也需要管理。因为这个原因,Oracle使用全局资源目录(GRD)和一些额外的后台进程。
(Oracle将V$视图加上实例标识组合起来形成GV$视图,一个GV$视图包含了集群中所有实例的动态性能视图)
全局资源目录 (GRD)
RAC中使用了一些附加的后台进程来做缓存间的同步——记住RAC使用cache fusion结构来模拟一个横跨集群内所有节点的全局SGA。访问buffer cache中的块需要在读一致和写的访问间进行协调,共享资源的队列现在也是在集群全局上的。全局缓存服务(Global Cache Service GCS)用来对公共buffer cache的访问,全局队列服务(Global Enqueue Service GES)用来管理集群中的队列。
GCS和GES对应用而言都是透明的。内部使用的原结构就是先前提到的GRD,由GCS和GES进程来维护。GRD分布在集群的所有节点上,是SGA的一部分,这就是为什么一个RAC数据库的SGA比同等情况下的单实例数据库要来得大。资源管理由GCS和GES来协商。特定的资源完全由一个实例来管理,这个实例就是resource master。但它并是不固定的,Oracle 9.2以后的版本实现了动态的资源管理(DRM),在9.2以前,资源的remastering只发生在实例故障、GRD重建的时候。新的版本中,如果Oracle检测到一个resource master以外的实例在一个给定的时间间隔中对一个特定的资源的访问过于频繁,就会发生resource mastering。在这种情况下,该资源就会被remaster到其他节点上,也就是说,频繁访问该资源的另一个节点将成为resource master。很多用户反馈了动态remastering的一些问题,当它过于频繁发生的时候会造成一些不必要的开支。这种情况下,可以禁用DRM。
(GRD还记录了哪些资源由哪些实例来管理,当一个实例发生故障时,恢复起来将非常方便)
(GRD还记录了哪些资源由哪些实例来管理,当一个实例发生故障时,恢复起来将非常方便)
下图说明GCS如何与GES协同工作来维护GRD
全局缓存服务(GCS)
LMSn后台进程使用GCS在全局buffer cache中维护缓存的一致性,SGA中可以存在同一个数据块的多份拷贝(当前版本只有一个),GCS对数据块的状态和位置进行跟踪,并通过内部连接将块传输到其他节点的实例中。
全局队列服务(GES)
和GCS类似,GES工作在块级别,管理集群中的全局队列。根据经验,如果一个操作没有涉及在全局buffer cache中控制/移动数据块,那么很可能是经过了GES的处理。全局队列服务负责所有的实例中的资源操作,比如对数据字典和库缓存的访问或事务的全局管理。它同样可以检测集群中的死锁。它跟踪多个实例同时访问资源时Oracle队列机制的状态。全局队列服务监控(LMON)和全局队列服务后台进程(LMD)组成全局队列服务的一部分。锁进程LCK0负责无缓存方式的访问,比如library和row cache请求。
缓存融合(Cache Fusion)
缓存融合是实例间数据传送的最新演变。Oracle 8i中曾使用block ping的机制,作为替代,Oracle使用高速的内部连接来为所有节点间的读写转移数据块。
实例间使用block ping方法来转移数据块代价是很昂贵的,它建议你将工作量与实例联系在一起来使实例间的数据块转移达到最少。在Oracle并行服务器(Oracle Parallel Server)中,当一个实例请求一个数据块来进行修改,而这个数据块当前正由别的实例所持有,它将发出一个信号给持有该块的实例,使其将块写入到磁盘,再发回该块已经可读的信号。这种方法的通讯和对磁盘的读写操作的量很不尽如人意。
缓存融合的块转移依赖于全局资源目录,不需要超过3次跳跃(hop),这与安装及节点的个数有关。很明显,如果一个集群只有两个节点,那么有一个双向的缓存转移。如果多于2个节点,将跳跃数限制在3次是必要的。Oracle使用专用的等待事件来衡量涉及缓存的通讯,根据实际情况来决定做一个双向或是三向的缓存转移。
当一个实例通过缓存融合来请求一个数据块时,它首先与资源的master联系来确定这个资源的当前状态,如果这个资源没有正在被使用,那么它可以通过从本地磁盘读取以获得这个块。如果这个资源正在被使用,那么该资源master将把这个资源传递到发出请求的实例中。如果这个资源紧接着收到1个或多个实例的修改请求,将会把该资源添加进GRD,资源的master、请求者和持有者都可以不同,这种情况下最多需要三次跳跃来获得这个块。
上面提到的双向和三向的块转移与资源的管理方式有关。当资源的master持有被请求的资源,那么对数据块的请求就能马上得到满足并开始块的传输,这就是双向的通讯。在三向的情况中,请求者、master和持有者都不相同,那么该资源master需要转发这个请求,引发了新的跳跃。
从刚才的讨论中,你可以知道在全局buffer cache中对块和它们影像间协调是不能低估的。在RAC数据库中,缓存融合常常代表了最大的利益和最高的成本。好处是缓存融合理论上运行按比例增大,并可能取得近乎线性的扩展性。然而,缓存融合强加的额外工作量可能会在10%-20%的范围内。
读一致性
Oracle数据库的主要特征之一就是能同时提供不同视野下的数据,这个特征叫做多版本读一致。查询是读一致的,写不会阻塞读,反之亦然。当然,多版本读一致对RAC一样有效,但涉及到一点其他的工作。
System Change Number(SCN)是一个Oracle的内部时间戳,对读一致非常重要。如果本地实例请求一个块的读一致版本,它需要联系这个块的resource master来确定这个块是否有相同SCN的版本,或者更新的版本存在于某个远程实例的buffer cache中。如果这个块存在,那么resource master会发送请求给相应的远程实例来转发这个块的读一致版本给本地实例。如果远程实例持有这个块的请求时间SCN的版本,那么它会马上发送这个块。如果远程实例持有的是这个块更新的版本,它将创建这个块的拷贝(称为前镜像),并对这个拷贝应用回滚使其回到对应的SCN的状态,然后将其通过内部连接发送。
System Change Number(SCN)
SCN是Oracle数据库产生和使用的内部时间戳,数据库中发生的所有事件都以SCN标记,事务也一样。Oracle的读一致严重依赖于SCN和undo表空间中的信息。SCN需要在集群中同步,RAC中用来使SCN在所有节点间通用的方案有两个:broadcast-on-commit和Lamport。
broadcast-on-commit是10.2以后的默认方案,它解决了Lamport方案的一个问题:在以前,这个默认方案是Lamport,它承诺了更好的扩展性,让SCN像集群其他通讯一样来传播,但并不是在一个节点中commit后马上发生。这在大部分情况下都能满足要求,但是,Lamport方案有一个问题:一个节点的SCN相对另一个节点的SCN有延时是可能的,特别是在在消息传送不活跃的时候。这种SCN的延时意味着在一个节点上提交的事务从另一个延时的实例上“看起来”会有点太新了。
另一方面,broadcast-on-commit方案更加资源集中一点。LGWR进程在每次commit之后更新全局的SCN并将其广播到所有的其他实例中。在RAC11.1中,初始化参数max_commit_propagation_delay允许数据库管理员来修改默认的设定,这个参数在11.2中被移除。
转载:http://blog.sina.com.cn/s/blog_5fe8502601016avf.html