暂无图片
暂无图片
3
暂无图片
暂无图片
2
暂无图片

Oracle RAC 详解(三)

原创 willsonli 云和恩墨 2022-04-18
4413

六、CRS

(一)CRSD功能介绍

CRSD的主要功能是管理集群中的应用程序(或者说是应用程序对应的资源),以便实现集群资源的高可用性。CRSD的另一部分功能就是管理OCR,包括OCR的更新和备份。

1. 10gR2版本

(1)基本概念

下面是一些和CRSD相关的基本概念。

资源:集群所管理的应用程序实体或者守护进程。资源分为本地资源和集群资源两种。本地资源只能在集群的某一个节点上运行,不能被切换到其他节点上运行。集群资源正常情况下会在默认的节点上运行,但是可以根据不同的情况切换到其他节点上。

资源概要文件:概要文件定义了资源的很多属性,以便CRSD能够根据概要文件定义的属性来管理该资源,例如:检查间隔、动作脚本等。

动作:动作定义了CRSD对资源进行启动、停止和检查操作时所需要运行的步骤,它可以是一段shell脚本、一段应用程序、数据库命令等。

状态:当某一个动作发生在一个资源上之后,一定会返回一个状态作为动作的输出。资源的状态可以是以下的几种之一。

ONLINE:在线,对应资源的online状态。

OFFLINE:离线,对应资源的offline状态。当然,即使资源被离线,GI仍然会探测这个资源的状态,以便在资源恢复正常时能够自动将资源重新上线。

UNKNOWN:未知,对应资源的unknown状态。在这种状态下,CRSD会持续对该资源进行检查,以便在资源恢复正常后能够发现它的新状态。

依赖关系(Dependency):资源之间并不是独立的,有些资源之间是存在互相依赖关系的。例如:数据库实例启动的前提是ASM实例要先被启动,这表示数据库实例资源需要依赖于ASM实例资源。而这种依赖关系是通过资源属性REQUIRED_RESOURCES来实现的。

权限:由于不同的资源需要执行的操作也是不同的,这意味着执行操作的用户也会不同(主要是root和Oracle用户),所以每个资源都会针对不同的用户指定不同的权限。这也是为什么crsd.bin守护进程需要以root用户运行的原因之一。

RACG模块:RACG模块实现了不同资源的具体动作定义,不同的racg模块负责不同的资源,例如:racgvip模块定义了对VIP的启动、停止和检查操作。

OCR(Oracle Cluster Register):OCR实际上是一个包含了以上所有信息的注册表,CRSD通过访问OCR来获得集群资源的列表(当然,还包括其他很重要的信息),以及每个资源的各个属性。可以说OCR就相当于CRSD或者集群的数据字典,集群中所有的属性和资源的属性都能在OCR中找到。

OCR主节点(OCR Master Node):由于集群中每个节点的crsd.bin守护进程都需要访问OCR,而且有时需要修改其中的信息,所以集群中最先启动的节点上的crsd.bin会被选择去修改OCR的进程,而对应的节点被称为OCR主节点。集群中的其他节点只会在本地将OCR的信息维护在cache(就是所谓的OCR cache)中,在读取信息时从cache中读取,而在写入时,会将对应的信息发送给OCR主节点,由主节点完成最后的写入操作。

在OCR主节点的crsd.log日志中会出现以下的关键字“I AM THE NEW OCR MASTER”。

(2)OCR的详细介绍

接下来详细地介绍关于OCR的内容,对于OCR的定义,在第5章和本章之前的部分已经做了基本的介绍,故不再重复。让我们先来看一下OCR的位置和结构。

① OCR位置

OCR的位置是通过文件/etc/oracle/ocr.loc来定义的,例如:

[oracle@test2 ~]$ cat /etc/oracle/ocr.loc ocrconfig_loc=/dev/raw/raw1 local_only=FALSE
复制

其中:

ocrconfig_loc指定OCR的位置。如果为OCR指定了镜像(Mirror),还会出现选项ocrmirrorconfig_loc,用于定义OCR镜像的位置。

local_only指定是否是RAC系统,如果这个值为FALSE,表示是RAC系统,如果这个值为TRUE,表示是单实例系统(在使用ASM时需要)。

我们能看到OCR的位置是/dev/raw/raw1,这是一块裸设备,所以OCR实际上有自己的格式而不是文本文件。另外OCR和OCR镜像中的信息是完全一致的,OCR镜像的主要作用就是为OCR提供冗余。当OCR出现问题而无法被访问时,系统会自动开始访问OCR镜像文件,确保集群正常运行。当OCR修复后,集群会重新读取OCR中的信息。

② OCR结构

如果需要查看OCR中的信息,可以使用命令“OCRDUMP”获得OCR的转储文件。例如:

[root@test2 bin]# ./ocrdump /tmp/ocrdump [SYSTEM] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.css] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.css.interfaces] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_CREATE_SUB_KEY,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : oinstall} [SYSTEM.css.interfaces.global] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : oinstall} [SYSTEM.css.interfaces.global.eth0] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : oinstall} [SYSTEM.css.interfaces.global.eth0.10|d182|d208|d0] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : oinstall} …… [SYSTEM.css.clustername] ORATEXT : crs SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.css.misscount] UB4 (10) : 60 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.css.diskfile] ORATEXT : /dev/raw/raw2 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root}
复制

这部分信息主要是集群CSS部分的定义性信息,我们能从中看到集群的名称、集群使用的网卡信息(包含公网和私网的详细信息,具体有主机名、IP地址、子网掩码等)、集群的misscount设置、VF位置等。

…… [SYSTEM.evm] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.evm.cevmkey] ORATEXT : 4377844 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.evm.rmport] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.evm.rmport.localhost] ORATEXT : (ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=49897)) SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root}
复制

这是集群EVM部分的配置信息,主要是EVM之间的通信配置信息。

…… [SYSTEM.crs] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.crs.usersecurity] ORATEXT : 1 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.crs.deny] ORATEXT : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.crs.user_default_dir] ORATEXT : /u01/app/crs/crs/public SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.crs.e2eport] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.crs.e2eport.test1] ORATEXT : (ADDRESS=(PROTOCOL=tcp)(HOST=test1-pri)(PORT=49896)) SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.crs.e2eport.test2] ORATEXT : (ADDRESS=(PROTOCOL=tcp)(HOST=test2-pri)(PORT=49896)) SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.crs.uiport] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.crs.uiport.test1] ORATEXT : (ADDRESS=(PROTOCOL=ipc)(KEY=CRSD_UI_SOCKET)) SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root}
复制

这部分主要定义了CRSD层面的配置信息,即CRSD的验证信息,以及CRSD之间的通信配置。

…… [SYSTEM.OCR] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.OCR.BACKUP] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.OCR.BACKUP.0] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.OCR.BACKUP.0.NODENAME] ORATEXT : test2 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.OCR.BACKUP.0.TIMESTAMP] ORATEXT : 2014/11/17 09:57:37 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [SYSTEM.OCR.BACKUP.0.LOC] ORATEXT : /u01/app/crs/cdata/crs
复制

这部分信息主要定义了OCR备份相关的配置信息。

…… [DATABASE] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_CREATE_SUB_KEY,OTHER_PERMISSION : PROCR_CREATE_SUB_KEY,USER_NAME : root,GROUP_NAME : root} [DATABASE.NODEAPPS] UNDEF : SECURITY : {USER_PERMISSION : PROCR_CREATE_SUB_KEY,GROUP_PERMISSION : PROCR_CREATE_SUB_KEY,OTHER_PERMISSION : PROCR_CREATE_SUB_KEY,USER_NAME : oracle,GROUP_NAME: oinstall} [DATABASE.NODEAPPS.test1] ORATEXT : test1 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [DATABASE.NODEAPPS.test1.ORACLE_HOME] ORATEXT : /u01/app/crs SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [DATABASE.NODEAPPS.test1.VIP] ORATEXT : test1-vip SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [DATABASE.NODEAPPS.test1.VIP.IP] ORATEXT : test1-vip SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} …… [DATABASE.ASM] UNDEF : SECURITY : {USER_PERMISSION : PROCR_CREATE_SUB_KEY,GROUP_PERMISSION : PROCR_CREATE_SUB_KEY,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : oinstall} [DATABASE.ASM.test1] ORATEXT : test1 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : dba} [DATABASE.ASM.test1.+asm1] ORATEXT : +ASM1 SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : dba} [DATABASE.ASM.test1.+asm1.ORACLE_HOME] ORATEXT : /u01/app/database SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : dba} [DATABASE.ASM.test1.+asm1.START_OPTIONS] ORATEXT : mount SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_ALL_ACCESS,OTHER_PERMISSION : PROCR_READ,USER_NAME : oracle,GROUP_NAME : dba}
复制

这部分主要定义了一部分与集群相关的资源的信息,更详细的信息是在[CRS]部分记录的。

…… [CRS] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_READ,OTHER_PERMISSION : PROCR_READ,USER_NAME : root,GROUP_NAME : root} [CRS.CUR] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_NONE,OTHER_PERMISSION : PROCR_NONE,USER_NAME : root,GROUP_NAME : root} [CRS.CUR.ora!test1!vip] UNDEF : SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_NONE,OTHER_PERMISSION : PROCR_NONE,USER_NAME : root,GROUP_NAME : root} [CRS.CUR.ora!test1!vip.ACTION_SCRIPT] ORATEXT : /u01/app/crs/bin/racgwrap SECURITY : {USER_PERMISSION : PROCR_ALL_ACCESS,GROUP_PERMISSION : PROCR_NONE,OTHER_PERMISSION : PROCR_NONE,USER_NAME : root,GROUP_NAME : root} ……
复制

这部分信息包含了CRSD所管理的所有资源的详细定义信息。

事实上,根据以上的OCR转储信息,结合之前章节对Oracle集群管理软件各个组件的介绍,读者大概能够看出OCR的结构具有以下几个特点:

特点1:OCR的逻辑结构是树形的层次结构,也就是说每个键值是由若干个层次构成的,层次之间是由符号“.”来分割的,最终的叶子负责保存具体的键值(有点像Windows的注册表)。我们也可以用下面的图形更加形象地说明。

image.png

特点2:OCR主要包含了以下三部分的内容。

SYSTEM:这部分包含了集群的CSS、CRS和EVM三个组件的重要配置信息,例如CSS层面的集群网络(公网和私网)配置信息、misscount值、VF名称;CRS层面的安全和验证配置信息、CRSD之间的通信配置;EVM层面的通信配置。还有集群版本历史、语言、OCR备份信息等。

DATABASE:这部分信息包含集群定义的资源的一部分配置信息。这部分信息主要是被srvctl和一些其他的集群配置工具所使用的,例如:VIPCA、dbca、netca等。

CRS:这部分信息记录着CRSD管理的所有资源的属性,CRSD在管理资源时使用这部分信息对集群的资源进行操作。

特点3:OCR的信息是会被备份的。OCR主节点上的crsd.bin会每隔4小时备份一次OCR,并且将备份最长保留一个星期。我们可以通过命令ocrconfig-showbackup来了解OCR的备份信息。

test2 2014/11/17 23:46:53 /u01/app/crs/cdata/crs test2 2014/11/17 19:46:52 /u01/app/crs/cdata/crs test2 2014/11/17 15:46:37 /u01/app/crs/cdata/crs test2 2014/11/17 09:57:37 /u01/app/crs/cdata/crs test1 2014/11/14 07:30:43 /u01/app/crs/cdata/crs [root@test2 bin]# pwd /u01/app/crs/bin [root@test2 bin]# ls -l /u01/app/crs/cdata/crs total 34008 -rw-r--r-- 1 root root 4964352 Nov 17 23:46 backup00.ocr -rw-r--r-- 1 root root 4964352 Nov 17 19:46 backup01.ocr -rw-r--r-- 1 root root 4964352 Nov 17 15:46 backup02.ocr -rw-r--r-- 1 root root 4964352 Nov 12 02:06 day_.ocr -rw-r--r-- 1 root root 4964352 Nov 17 09:57 day.ocr -rw-r--r-- 1 root root 4964352 Nov 8 02:05 week_.ocr -rw-r--r-- 1 root root 4952064 Oct 27 03:51 week.ocr
复制

我们能看到backup00.ocr、backup01.ocr的时间间隔是4个小时。当天的备份产生于Nov 17 09:57并且保存在节点test2上,而最近一个星期的备份产生于Nov 17 09:57,并且保存在节点test1上。

特点4:OCR中的每一个键值都是由三部分构成的,分别是键值名称、对应值(ORATEXT)和安全属性(SECURITY)。

③ OCR管理

既然OCR是一个层次结构组织的文件,而且其中的信息会被动态修改,这也就意味着OCR是有可能出现损坏(corruption)情况的(就像数据库会出现坏块一样)。如果需要检测OCR是否出现了问题,可以使用命令ocrcheck进行检查。例如:

[root@test2 bin]# ./ocrcheck Status of Oracle Cluster Registry is as follows : Version : 2 Total space (kbytes) : 2096108 Used space (kbytes) : 4604 Available space (kbytes) : 2091504 ID : 623535930 Device/File Name : /dev/raw/raw1 Device/File integrity check succeeded Device/File not configured Cluster registry integrity check succeeded
复制

从上面的输出能看到,这个工具对OCR所在文件的一致性,以及OCR的内容一致性进行了验证,但是,对于10gR2版本的ocrcheck命令,OCR的逻辑一致性是不会被验证的。从11gR1版本开始,ocrcheck命令增加了对OCR的逻辑一致性验证。例如:

[root@test1 ~]# /u01/app/11.2.0.4/grid/bin/ocrcheck Status of Oracle Cluster Registry is as follows : Version : 3 Total space (kbytes) : 262120 Used space (kbytes) : 3524 Available space (kbytes) : 258596 ID : 644165673 Device/File Name : +DATA1 Device/File integrity check succeeded Device/File not configured Device/File not configured Device/File not configured Device/File not configured Cluster registry integrity check succeeded Logical corruption check succeeded
复制

我们可以看到逻辑一致性检查被执行了(Logical corruption check succeeded)。

因此,一旦OCR出现了损坏,该如何恢复呢?基于我们之前介绍的内容,OCR每4个小时会被自动备份,答案自然是从之前的备份中恢复,可以使用ocrconfig工具对OCR进行恢复。例如:

步骤1:查看最新的OCR备份位置。

test2 2014/11/17 23:46:53 /u01/app/crs/cdata/crs test2 2014/11/17 19:46:52 /u01/app/crs/cdata/crs test2 2014/11/17 15:46:37 /u01/app/crs/cdata/crs test2 2014/11/17 09:57:37 /u01/app/crs/cdata/crs test1 2014/11/14 07:30:43 /u01/app/crs/cdata/crs [root@test2 bin]# pwd /u01/app/crs/bin [root@test2 bin]# ls -l /u01/app/crs/cdata/crs total 34008 -rw-r--r-- 1 root root 4964352 Nov 17 23:46 backup00.ocr -rw-r--r-- 1 root root 4964352 Nov 17 19:46 backup01.ocr -rw-r--r-- 1 root root 4964352 Nov 17 15:46 backup02.ocr -rw-r--r-- 1 root root 4964352 Nov 12 02:06 day_.ocr -rw-r--r-- 1 root root 4964352 Nov 17 09:57 day.ocr -rw-r--r-- 1 root root 4964352 Nov 8 02:05 week_.ocr -rw-r--r-- 1 root root 4952064 Oct 27 03:51 week.ocr
复制

步骤2:在所有节点上停止集群。

[root@test2 bin]# ./crsctl stop crs Stopping resources. This could take several minutes. Successfully stopped CRS resources. Stopping CSSD. Shutting down CSS daemon. Shutdown request successfully issued.
复制

步骤3:从备份中恢复OCR。

[root@test2 bin]# ./ocrconfig -restore /u01/app/crs/cdata/crs/backup00.ocr
复制

crsd.bin在对OCR进行备份时是不会进行验证的,所以在恢复之前需要使用命令ocrdump–backupfile<文件名>来确认OCR备份是否也已损坏。如果所有的OCR备份都已经损坏,那么只能通过重建OCR的方式来修复损坏。

而另外的修复OCR损坏的方式是:

①通过OCR的转储文件找到损坏的位置。

②通过集群中的命令(例如:crsctl、srvctl、crs_register、crs_unregister)重建损坏的键值。

对于这种修复方式,需要具体情况具体分析,无法介绍详细的步骤。

最后,OCR中的坏块和数据库中的坏块是比较类似的。损坏的键值不同,带来的影响也不尽相同,有可能会导致集群无法启动,也可能对集群的正常运行没有任何影响。就像数据库的坏块一样,如果损坏的块位于系统表空间的bootstrap部分,那么可能导致数据库无法启动,如果坏块的位置是在一个历史表当中,而这个表永远也不会被应用去访问,那么数据库完全可以正常运行。

(3)crsd.bin守护进程

10g版本的crsd.bin守护进程的功能相对来说是比较简单的,主要有:

1)读取OCR中的信息,对集群的资源执行启动、停止和检查等操作。

2)每4个小时对OCR进行备份。

3)和其他节点的crsd.bin进行通信。

4)处理用户或者集群发出的各种命令。

接下来会通过在一些不同场景下取得的crsd.bin的日志文件(crsd.log)来说明crsd.bin守护进程的功能。

① crsd.bin守护进程启动
Oracle Database 10g CRS Release 10.2.0.5.0 Production Copyright 1996,2004,Oracle. All rights reserved <<<<< 2014-11-18 07:47:36.308: [default][2352832]0CRS Daemon Starting 2014-11-18 07:47:36.312: [CRSMAIN][2352832]0Checking the OCR device 2014-11-18 07:47:36.763: [CRSMAIN][2352832]0Connecting to the CSS Daemon 2014-11-18 07:47:37.355: [COMMCRS][118033296]clsc_connect: (0x8822f50) no listener at (ADDRESS=(PROTOCOL=ipc)(KEY=OCSSD_LL_test1_)) <<<<< 2014-11-18 07:47:37.355: [CSSCLNT][2352832]clsssInitNative: connect failed,rc 9 2014-11-18 07:47:37.357: [CRSRTI][2352832]0CSS is not ready. Received status 3 from CSS. Waiting for good status .
复制

可以看到,集群的版本是10.2.0.5。crsd.bin守护进程启动后会先检查ocssd.bin守护进程是否已经启动成功,如果没有启动成功,则需要等待,当ocssd.bin守护进程被成功启动之后,crsd.bin才能继续向下运行。而且,我们能够发现crsd.bin和ocssd.bin之间的通信是通过套接字(ADDRESS=(PROTOCOL=ipc)(KEY=OCSSD_LL_test1_))进行的,这也是本书作者一直强调/var/tmp/.oracle(不同的操作系统路径不一样)下的套接字文件不能够手动删除的原因。

…… 2014-11-18 07:47:55.618: [CLSVER][2352832]0Active Version from OCR:10.2.0.5.0 2014-11-18 07:47:55.618: [CLSVER][2352832]0Active Version and Software Version are same 2014-11-18 07:47:55.619: [CRSMAIN][2352832]0Initializing OCR <<<<< 2014-11-18 07:47:57.424: [OCRRAW][2352832]proprioo: for disk 0 (/dev/raw/raw1),id match (1),my id set (1669906634,1028247821) total id sets (1),1st set (1669906634,1028247821),2nd set (0,0) my votes (2),total votes (2) <<<<<
复制

可以看到,当ocssd.bin守护进程启动成功之后,crsd.bin守护进程开始读取OCR,并对OCR进行初始化操作。

…… 2014-11-18 07:47:58.662: [CRSD][2352832]0ENV Logging level for Module: allcomp 0 <<<<< 2014-11-18 07:47:58.668: [CRSD][2352832]0ENV Logging level for Module: default 0 2014-11-18 07:47:58.812: [CRSD][2352832]0ENV Logging level for Module: COMMCRS 0 2014-11-18 07:47:58.826: [CRSD][2352832]0ENV Logging level for Module: COMMNS 0 2014-11-18 07:47:58.845: [CRSD][2352832]0ENV Logging level for Module: CRSUI 0 2014-11-18 07:47:58.848: [CRSD][2352832]0ENV Logging level for Module: CRSCOMM 0
复制

接下来crsd.bin的各个模块(module)被启动。

…… 2014-11-18 07:47:59.695: [CRSMAIN][2352832]0Filename is /u01/app/crs/crs/init/test1.pid <<<<< [clsdmt][2856106896]Listening to (ADDRESS=(PROTOCOL=ipc)(KEY=test1DBG_CRSD)) <<<<< 2014-11-18 07:48:00.201: [CRSMAIN][2352832]0Using Authorizer location: /u01/app/crs/crs/auth/ <<<<< …… 2014-11-18 07:48:06.535: [CRSMAIN][2352832]0QS socket on: (ADDRESS=(PROTOCOL=ipc)(KEY=ora_crsqs)) 2014-11-18 07:48:06.535: [CRSMAIN][2352832]0QS socket on: (ADDRESS=(PROTOCOL=ipc)(KEY=ora_crsqs)) 2014-11-18 07:48:07.450: [CRSMAIN][2352832]0CRSD UI socket on: (ADDRESS=(PROTOCOL=ipc)(KEY=CRSD_UI_SOCKET)) <<<<< 2014-11-18 07:48:07.584: [CRSMAIN][2352832]0E2E socket on: (ADDRESS=(PROTOCOL=tcp)(HOST=test1-pri)(PORT=49896)) <<<<< 2014-11-18 07:48:07.584: [CRSMAIN][2352832]0Starting Threads 2014-11-18 07:48:07.585: [CRSMAIN][2352832]0CRS Daemon Started.
复制

然后,crsd.bin守护进程创建了自己的pid文件和套接字,并指定了认证路径。之后crsd.bin为UI(User Interface)功能创建了套接字。(ADDRESS=(PROTOCOL=ipc)(KEY=CRSD_UI_SOCKET)),所谓UI就是用于处理用户所发送的命令的接口。之后还创建了和远程crsd.bin守护进程通信所需的套接字。(ADDRESS=(PROTOCOL=tcp)(HOST=test1-pri)(PORT=49896))。最后,crsd.bin守护进程启动成功。

…… 2014-11-18 07:48:15.186: [CRSRES][2719738768]0Attempting to start `ora.test1.ASM1.asm` on member `test1` <<<<< 2014-11-18 07:48:16.965: [CRSRES][2730228624]0startRunnable: setting CLI values 2014-11-18 07:48:16.966: [CRSRES][2730228624]0Attempting to start `ora.test1.vip` on member `test1` 2014-11-18 07:48:24.768: [CRSRES][2730228624]0Start of `ora.test1.vip` on member `test1` succeeded. <<<<< …… 2014-11-18 07:48:52.808: [CRSRES][2730228624]0Attempting to start `ora.test1.ons` on member `test1` <<<<< 2014-11-18 07:48:55.391: [CRSRES][2730228624]0Start of `ora.test1.ons` on member `test1` succeeded. 2014-11-18 07:48:55.460: [CRSRES][2719738768]0Start of `ora.test1.ASM1.asm` on member `test1` succeeded. <<<<< 2014-11-18 07:48:55.838: [CRSRES][2719738768]0startRunnable: setting CLI values 2014-11-18 07:48:55.859: [CRSRES][2719738768]0Attempting to start `ora.ora10g.ora10g1.inst` on member `test1` 2014-11-18 07:49:30.967: [CRSRES][2719738768]0Start of `ora.ora10g.ora10g1.inst` on member `test1` succeeded.
复制

crsd.bin根据OCR中的信息启动了集群的资源。

② crsd.bin守护进程关闭

作者使用命令crsctl stop crs来停止集群。

2014-11-18 11:40:08.464: [CRSD][2719738768]0SM: Recovery processing done.0 2014-11-18 11:40:08.464: [CRSD][2719738768]0SM: Ongoing commands done.0 <<<<< 2014-11-18 11:40:08.505: [CRSD][2719738768]0SM: asked E2E to exit. 2014-11-18 11:40:08.505: [CRSCOMM][2772188048]0CLEANUP: quiesceing connection 0x8cde380 <<<<< 2014-11-18 11:40:08.507: [CRSMAIN][2772188048]0runCommandServer for E2E exiting. <<<<< 2014-11-18 11:40:08.507: [CRSD][2719738768]0SM: E2E port closed.3 <<<<<
复制

可以看到,crsd.bin首先会完成所有正在执行的操作,之后静默所有的连接,这样做的目的是为了保证OCR的一致性,避免一些已经存在的操作或者正在运行的操作引起OCR被损坏。最后与远程crsd.bin守护进程之间的连接被关闭。

…… 2014-11-18 11:40:08.507: [CRSD][2719738768]0SM: stoppedResources: all =1 m_state = 3 2014-11-18 11:40:08.643: [CRSRES][2772188048]0StopResource: setting CLI values 2014-11-18 11:40:08.794: [CRSRES][2730228624]0StopResource: setting CLI values 2014-11-18 11:40:08.917: [CRSRES][2772188048]0Attempting to stop `ora.test1.gsd` on member `test1` 2014-11-18 11:40:08.980: [CRSRES][2665470864]0StopResource: setting CLI values 2014-11-18 11:40:09.000: [CRSRES][2709248912]0StopResource: setting CLI values 2014-11-18 11:40:09.072: [CRSRES][2665470864]0Attempting to stop `ora.ora10g.test_TAF.cs` on member `test1` 2014-11-18 11:40:09.158: [CRSRES][2709248912]0Attempting to stop `ora.ora10g.test_TAF.ora10g1.srv` on member `test1` 2014-11-18 11:40:09.206: [CRSRES][2730228624]0Attempting to stop `ora.test1.ons` on member `test1` 2014-11-18 11:40:09.459: [CRSRES][2709248912]0Stop of `ora.ora10g.test_TAF.ora10g1.srv` on member `test1` succeeded. 2014-11-18 11:40:09.611: [CRSRES][2665470864]0Stop of `ora.ora10g.test_TAF.cs` on member `test1` succeeded. 2014-11-18 11:40:09.907: [CRSRES][2772188048]0Stop of `ora.test1.gsd` on member `test1` succeeded. 2014-11-18 11:40:10.112: [CRSRES][2730228624]0Stop of `ora.test1.ons` on member `test1` succeeded. 2014-11-18 11:40:10.223: [CRSRES][2709248912]0StopResource: setting CLI values 2014-11-18 11:40:10.267: [CRSRES][2709248912]0Attempting to stop `ora.ora10g.ora10g1.inst` on member `test1` 2014-11-18 11:40:10.272: [CRSRES][2665470864]0StopResource: setting CLI values 2014-11-18 11:40:10.356: [CRSRES][2665470864]0Attempting to stop `ora.test1.LISTENER_TEST1.lsnr` on member `test1` 2014-11-18 11:40:10.960: [CRSMAIN][2761698192]0UI Cmd received after shutdown began. 2014-11-18 11:40:11.134: [CRSRES][2665470864]0Stop of `ora.test1.LISTENER_TEST1.lsnr` on member `test1` succeeded. 2014-11-18 11:40:11.177: [CRSRES][2665470864]0StopResource: setting CLI values 2014-11-18 11:40:11.349: [CRSRES][2665470864]0StopResource: setting CLI values 2014-11-18 11:40:11.355: [CRSRES][2665470864]0Attempting to stop `ora.test1.vip` on member `test1` 2014-11-18 11:40:11.856: [CRSMAIN][2761698192]0UI Cmd received after shutdown began. 2014-11-18 11:40:12.313: [CRSRES][2665470864]0Stop of `ora.test1.vip` on member `test1` succeeded. 2014-11-18 11:40:12.880: [CRSMAIN][2761698192]0UI Cmd received after shutdown began. 2014-11-18 11:40:12.970: [CRSRES][2709248912]0Stop of `ora.ora10g.ora10g1.inst` on member `test1` succeeded. 2014-11-18 11:40:13.004: [CRSRES][2709248912]0StopResource: setting CLI values 2014-11-18 11:40:13.038: [CRSRES][2709248912]0StopResource: setting CLI values 2014-11-18 11:40:13.055: [CRSRES][2709248912]0Attempting to stop `ora.test1.ASM1.asm` on member `test1` 2014-11-18 11:40:14.054: [CRSMAIN][2761698192]0UI Cmd received after shutdown began. 2014-11-18 11:40:15.025: [CRSRES][2709248912]0Stop of `ora.test1.ASM1.asm` on member `test1` succeeded. 2014-11-18 11:40:15.169: [CRSEVT][2751208336]0Error dispatching EVM event; reconnecting 2014-11-18 11:40:15.208: [CSSCLNT][2866596752]clssgsGGetStatus: CSS shutting down. 2014-11-18 11:40:15.209: [CSSCLNT][2866596752]clssgsGGetStatus: returning 22 2014-11-18 11:40:15.209: [CRSD][2866596752]0CRSD exiting on CSS shutdown request 2014-11-18 11:40:15.209: [CRSD][2866596752]0Done.
复制

这一部分是关闭crsd.bin守护进程最主要的一部分,在这一部分CRSD开始关闭集群的所有资源,之后crsd.bin守护进程被

终止。实际上从上面日志中资源的关闭顺序大家可以看到,CRSD是按照资源的依赖关系来关闭资源的。

③ 手动关闭和启动资源

首先,我们使用下面的命令中止集群中一个节点的监听程序资源。

[oracle@test1 ~]$ date; srvctl stop listener -n test2 Tue Nov 18 13:33:29 CST 2014 [oracle@test1 ~]$ crs_stat -t Name Type Target State Host ------------------------------------------------------------ ora....SM1.asm application ONLINE ONLINE test1 ora....t1.lsnr application ONLINE ONLINE test1 ora....st1.gsd application ONLINE ONLINE test1 ora....st1.ons application ONLINE ONLINE test1 ora....st1.vip application ONLINE ONLINE test1 ora....SM2.asm application ONLINE ONLINE test2 ora....t2.lsnr application OFFLINE OFFLINE test2
复制

大家可以看到,作者使用上面的命令中止了远程节点的监听程序资源。下面,我们看一下两个节点的crsd.log日志文件。
对于节点1(test1),有:

2014-11-18 13:33:31.419: [CRSRES][2644437904]0Resource::stop invoked for ora.test2.LISTENER_TEST2.lsnr <<<<<< 2014-11-18 13:33:31.427: [CRSRES][2644437904]0Could not find recovery info for resource to purge:ora.test2.LISTENER_TEST2.lsnr 2014-11-18 13:33:31.443: [CRSRES][2644437904]0Resource::stopResource invoked 2014-11-18 13:33:31.462: [CRSRES][2644437904]0ora.test2.LISTENER_TEST2.lsnr target set to OFFLINE before stop action <<<<<< 2014-11-18 13:33:31.462: [CRSRES][2644437904]0StopResource: setting CLI values 2014-11-18 13:33:31.528: [CRSCOMM][2644437904]0Using cached E2E port: (ADDRESS=(PROTOCOL=tcp)(HOST=test2-pri)(PORT=49896)) <<<<<< 2014-11-18 13:33:31.550: [CRSCOMM][2644437904]0NAME: `ORDER` length=5 2014-11-18 13:33:31.551: [CRSRES][2644437904]0Attempting to stop `ora.test2.LISTENER_TEST2.lsnr` on member `test2` <<<<<< 2014-11-18 13:33:31.998: [CRSCOMM][2644437904]0NAME: `ORDER` length=5 2014-11-18 13:33:31.998: [CRSRES][2644437904]0Stop of `ora.test2.LISTENER_TEST2.lsnr` on member `test2` succeeded. <<<<<< 2014-11-18 13:33:31.999: [CRSCOMM][2644437904]0NAME: `UI_DATA` length=7 <<<<<< 2014-11-18 13:33:31.999: [CRSCOMM][2644437904]0Successfully read response 2014-11-18 13:33:32.008: [CRSRES][2644437904]0Adding result for ora.test2.LISTENER_TEST2.lsnr : 0 2014-11-18 13:33:32.009: [CRSRES][2644437904]0Skipping resource that doesnt require processing 2014-11-18 13:33:32.009: [CRSRES][2633948048][ENTER]0processWork 2014-11-18 13:33:32.009: [CRSRES][2633948048]0Concurrency is: 0 2014-11-18 13:33:32.009: [CRSRES][2633948048]0Number of threads spawned: 0
复制

从上面的日志输出可以看到,首先CRSD收到了停止资源的命令,由于需要停止远程节点的资源,crsd.bin利用和远程节点通信的套接字,在远程中止资源,最后将结果通过UI反馈给了发起命令的进程。

<crs_home>/bin/crsctl debug log crs CRSUI:4,CRSRES:4,CRSCOMM:4
复制

下面我们通过以下的命令重新启动之前被停止的监听程序资源。

[oracle@test1 crsd]$ date; srvctl start listener -n test2 Tue Nov 18 13:51:16 CST 2014 [oracle@test1 crsd]$ crs_stat -t Name Type Target State Host ------------------------------------------------------------ ora....SM1.asm application ONLINE ONLINE test1 ora....t1.lsnr application ONLINE ONLINE test1 ora....st1.gsd application ONLINE ONLINE test1 ora....st1.ons application ONLINE ONLINE test1 ora....st1.vip application ONLINE ONLINE test1 ora....SM2.asm application ONLINE ONLINE test2 ora....t2.lsnr application ONLINE ONLINE test2
复制

看起来监听程序资源被重新启动了,我们来看一下对应的crsd.log。

对于节点1(test1),有:

2014-11-18 13:51:16.793: [CRSRES][2644437904]0Evaluating: ora.test2.LISTENER_TEST2.lsnr <<<<< 2014-11-18 13:51:16.793: [CRSRES][2644437904]0Adding resource to maintain graph shape ora.test2.vip <<<<< 2014-11-18 13:51:16.793: [CRSRES][2644437904][ENTER]0processWork 2014-11-18 13:51:16.793: [CRSRES][2644437904]0Concurrency is: 0 2014-11-18 13:51:16.793: [CRSRES][2644437904]0Number of threads spawned: 0 2014-11-18 13:51:16.793: [CRSRES][2644437904][ENTER]0processWork 2014-11-18 13:51:16.793: [CRSRES][2644437904]0Concurrency is: 1 2014-11-18 13:51:16.793: [CRSRES][2644437904]0Number of threads spawned: 1 2014-11-18 13:51:16.794: [CRSRES][2654927760][ENTER]0processlistStub 2014-11-18 13:51:16.794: [CRSRES][2654927760][ENTER]0StartWork::execute 2014-11-18 13:51:16.794: [CRSRES][2654927760]0Skipping resource that doesnt require processing 2014-11-18 13:51:16.794: [CRSRES][2654927760]0Resource::place invoked for ora.test2.LISTENER_TEST2.lsnr mode =1 2014-11-18 13:51:16.823: [CRSRES][2654927760]0Required resource: ora.test2.LISTENER_TEST2.lsnr is available. <<<<< 2014-11-18 13:51:16.823: [CRSRES][2654927760]0ora.test2.LISTENER_TEST2.lsnr requires: ora.test2.vip <<<<< 2014-11-18 13:51:16.829: [CRSRES][2654927760]0Required resource: ora.test2.vip is available. <<<<< 2014-11-18 13:51:16.846: [CRSRES][2654927760]0initial evalPlace status = 0 2014-11-18 13:51:16.846: [CRSRES][2654927760]0-------[Placement List for ora.test2.LISTENER_TEST2.lsnr]------- 2014-11-18 13:51:16.846: [CRSRES][2654927760]0ora.test2.LISTENER_TEST2.lsnr -> [test2] <<<<< 2014-11-18 13:51:16.846: [CRSRES][2654927760]0-------[Placement List]------- 2014-11-18 13:51:16.846: [CRSRES][2654927760]0p-list resource ora.test2.LISTENER_TEST2.lsnr 2014-11-18 13:51:16.847: [CRSRES][2654927760]0Successors: 2014-11-18 13:51:16.920: [CRSRES][2654927760]0starting place loop 2014-11-18 13:51:16.920: [CRSRES][2654927760]0Resource::startResource invoked for ora.test2.LISTENER_TEST2.lsnr <<<<< 2014-11-18 13:51:16.920: [CRSCOMM][2654927760]0Using cached E2E port: (ADDRESS=(PROTOCOL=tcp)(HOST=test2-pri)(PORT=49896)) <<<<< 2014-11-18 13:51:16.971: [CRSCOMM][2654927760]0NAME: `ORDER` length=5 2014-11-18 13:51:16.971: [CRSRES][2654927760]0Attempting to start `ora.test2.LISTENER_TEST2.lsnr` on member `test2` <<<<< 2014-11-18 13:51:17.372: [CRSCOMM][2654927760]0NAME: `ORDER` length=5 2014-11-18 13:51:17.372: [CRSRES][2654927760]0Start of `ora.test2.LISTENER_TEST2.lsnr` on member `test2` succeeded. <<<<< 2014-11-18 13:51:17.373: [CRSCOMM][2654927760]0NAME: `UI_DATA` length=7 <<<<< 2014-11-18 13:51:17.373: [CRSCOMM][2654927760]0Successfully read response
复制

根据上面的日志,我们可以看到在启动监听程序资源时,crsd.bin守护进程执行了以下的操作。

1)检查监听程序所依赖的资源是否有效(在本例中是VIP资源)。

2)决定要启动的监听程序资源应该在哪一个节点上被启动。

3)由于需要启动的资源位于远程节点上,crsd.bin通过对应的套接字在远程节点上启动资源。

4)资源在远程节点上被成功启动,相关命令被返回给了执行命令的用户进程。

④ 当资源出现问题时

我们使用下面的命令停止某一个节点的公网网卡,并查看对应集群资源的状态。

[root@test1 ~]# ifconfig eth0 down [oracle@test2 ~]$ crs_stat -t Name Type Target State Host ------------------------------------------------------------ ora....SM1.asm application ONLINE ONLINE test1 ora....t1.lsnr application ONLINE OFFLINE<<<<<<<<< ora....st1.gsd application ONLINE ONLINE test1 ora....st1.ons application ONLINE ONLINE test1 ora....st1.vip application ONLINE ONLINE test2<<<<<
复制

大家可以看到,当节点test1的公网网卡被停止后,test1上的VIP资源被切换到了节点test2上,而节点test1上的监听程序被终止。这些动作都是正常的行为。下面,我们看一下crsd.bin的日志文件里都记录了什么。

对于节点1(test1),有:

2014-11-18 14:05:12.959: [CRSAPP][2654927760]0CheckResource error for ora.test1.vip error code = 1 <<<<< 2014-11-18 14:05:12.967: [CRSRES][2654927760]0Recovery start: ora.test1.vip:1416290712 2014-11-18 14:05:12.967: [CRSRES][2654927760]0In stateChanged,ora.test1.vip target is ONLINE <<<<< 2014-11-18 14:05:12.968: [CRSRES][2654927760]0ora.test1.vip on test1 went OFFLINE unexpectedly <<<<< 2014-11-18 14:05:12.968: [CRSRES][2654927760]0Resource::stopResource invoked <<<<< 2014-11-18 14:05:12.968: [CRSRES][2654927760]0StopResource: setting CLI values 2014-11-18 14:05:12.987: [CRSRES][2654927760]0Attempting to stop `ora.test1.vip` on member `test1` <<<<<
复制

以上的日志表明:CRSD在检查VIP资源时发现了问题,之后决定停止该资源。

…… 2014-11-18 14:05:13.201: [CRSRES][2644437904]0Recovery start: ora.ora10g.test_TAF.ora10g1.srv:1416290713 2014-11-18 14:05:13.202: [CRSRES][2644437904]0In stateChanged,ora.ora10g.test_TAF.ora10g1.srv target is ONLINE 2014-11-18 14:05:13.202: [CRSRES][2644437904]0ora.ora10g.test_TAF.ora10g1.srv on test1 went OFFLINE unexpectedly …… 2014-11-18 14:05:13.220: [CRSRES][2644437904]0Attempting to stop `ora.ora10g.test_TAF.ora10g1.srv` on member `test1` 2014-11-18 14:05:13.891: [CRSRES][2644437904]0ora.ora10g.test_TAF.ora10g1.srv target set to OFFLINE after stop action succeeded 2014-11-18 14:05:13.891: [CRSRES][2644437904]0Stop of `ora.ora10g.test_TAF.ora10g1.srv` on member `test1` succeeded. 2014-11-18 14:05:13.894: [CRSRES][2644437904]0ora.ora10g.test_TAF.ora10g1.srv RESTART_COUNT=0 RESTART_ATTEMPTS=0
复制

以上的日志表明:数据库的service资源依赖于VIP资源,所以也被停止。

…… 2014-11-18 14:05:13.911: [CRSRES][2654927760]0ora.test1.vip target set to OFFLINE after stop action succeeded 2014-11-18 14:05:13.911: [CRSRES][2654927760]0Stop of `ora.test1.vip` on member `test1` succeeded. 2014-11-18 14:05:13.914: [CRSRES][2654927760]0ora.test1.vip RESTART_COUNT=0 RESTART_ATTEMPTS=0
复制

VIP资源停止成功。

…… 2014-11-18 14:05:14.063: [CRSRES][2654927760]0-------[Placement List for ora.test1.vip]------- 2014-11-18 14:05:14.063: [CRSRES][2654927760]0ora.test1.vip -> [test2] 2014-11-18 14:05:14.063: [CRSRES][2654927760]0ora.test1.LISTENER_TEST1.lsnr -> [] 2014-11-18 14:05:14.063: [CRSRES][2654927760]0-------[Placement List]------- ……
复制

接下来CRSD开始为VIP资源寻找新的节点,节点test2被发现。

…… 2014-11-18 14:05:14.167: [CRSRES][2654927760]0Attempting to stop `ora.test1.LISTENER_TEST1.lsnr` on member `test1` 2014-11-18 14:05:14.467: [CRSRES][2644437904]0Evaluating: ora.test1.LISTENER_TEST1.lsnr …… 2014-11-18 14:05:14.623: [CRSRES][2654927760]0ora.test1.LISTENER_TEST1.lsnr target set to OFFLINE after stop action succeeded 2014-11-18 14:05:14.623: [CRSRES][2654927760]0Stop of `ora.test1.LISTENER_TEST1.lsnr` on member `test1` succeeded.
复制

接下来,依赖于VIP的监听程序资源被停止。

2014-11-18 14:05:14.628: [CRSRES][2654927760]0Resource::startResource invoked for ora.test1.vip 2014-11-18 14:05:14.629: [CRSCOMM][2654927760]0Using cached E2E port: (ADDRESS=(PROTOCOL=tcp)(HOST=test2-pri)(PORT=49896)) 2014-11-18 14:05:14.688: [CRSCOMM][2654927760]0NAME: `ORDER` length=5 2014-11-18 14:05:14.688: [CRSRES][2654927760]0Attempting to start `ora.test1.vip` on member `test2` 2014-11-18 14:05:18.180: [CRSCOMM][2654927760]0NAME: `ORDER` length=5 2014-11-18 14:05:18.180: [CRSRES][2654927760]0Start of `ora.test1.vip` on member `test2` succeeded. …… 2014-11-18 14:05:18.181: [ CRSCOMM][2654927760]0Successfully read response
复制

crsd.bin守护进程和远程节点的CRSD守护进程通信,在节点test2上启动了本地节点的VIP资源,操作结束。

(4)CRSD管理的资源

在这部分内容中,作者会对10gR2版本的集群所管理的资源进行介绍。首先,简单介绍一下具体实现管理资源功能的各个racg模块。大家可以通过下面的图形简单地了解racg模块和对应资源的关系。

image.png

其中:

racgwrap:负责向racgmain模块提供环境变量,例如crs_home、oracle_home等。

racgmain:它是所有racg模块的主模块,具体定义了对每个资源的动作,如启动、停止和检查。

racgvip:它负责定义对VIP资源的启动、检查和停止操作。

racgons:它负责定义ONS资源的动作。

racgimon:它负责监控数据库或ASM实例的健康性。

对于数据库实例,racgimon是以进程的方式常驻在实例当中的,例如:

SQL> select sidserial#,program,username from v$session where program like 'racg%'SID SERIAL# PROGRAM USERNAME ---------- -------- ---------------------------------------- ---------- 137 59 racgimon@test2.cn.oracle.com (TNS V1-V3) SYS 138 19 racgimon@test2.cn.oracle.com (TNS V1-V3) SYS 139 5 racgimon@test2.cn.oracle.com (TNS V1-V3) SYS 141 5 racgimon@test2.cn.oracle.com (TNS V1-V3) SYS
复制

对于ASM实例,racgimon是以操作系统进程的方式存在的,例如:

[oracle@test1 bin]$ ps -ef | grep racg oracle 6843 1 0 13:28 ? 00:00:00 /u01/app/database/bin/racgimon daemon ora.test1.ASM1.asm oracle 6902 1 0 13:28 ? 00:00:01 /u01/app/database/bin/racgimon startd ora10g oracle 8351 24073 0 15:07 pts/6 00:00:00 grep racg
复制

racgmdb:它负责启动、关闭和检查实例。

接下来,我们开始逐一对CRSD所管理的主要集群资源进行介绍。

① VIP资源(ora.<节点名>.vip)

VIP(虚拟IP)技术实际上是很多集群管理软件都要提供的特性,它的主要目的就是防止下面的情况出现:当集群某一个(多个)节点宕机后,客户端的应用程序不能够马上被通知而会继续连接已经宕机的节点,从而导致应用程序需要等待TCP超时后才能返回错误。这种长时间的等待对于绝大多数高可用性系统来说是无法接受的。

不过,不同的集群管理软件实现VIP的方式不尽相同,叫法也不太一样,有些集群管理软件(例如:HACMP)为集群指定了唯一的VIP并称之为浮动IP,当运行浮动IP的节点出现问题之后,浮动IP可以飘移到集群的其他节点。

而Oracle集群管理软件的实现方法是:每个节点上都有属于本地节点的VIP,当一个节点出现问题时,本地节点的VIP会切换到集群的其他节点,如果大家看到某一个节点上出现了多个VIP地址的话,很可能是因为其他节点的VIP切换到了这个节点。

当然,另外一种可能就是用户自己创建了应用程序VIP(或者叫作自定义VIP),这种VIP实际上是用户为了实现自定义应用程序的高可用性而自己创建的VIP资源,其功能和Oracle提供的VIP基本上是一样的,不过本书不会对应用程序VIP做详细的介绍。

Oracle集群中的每一个节点都会拥有一个自己的VIP,当本地节点宕机或者公网出现问题时,VIP会切换到集群中的其他健康节点,而当本地节点恢复正常后,VIP会自动切换本地节点。

VIP资源是通过racgvip脚本来实现具体的启动、停止和检查工作的。以下是一段racgvip脚本的注释:

# Syntax: # # racgvip start vip_name # racgvip stop vip_name # racgvip check vip_name # racgvip create vip_name IP=vip_address NODE=preferred_node # [MASK=netmask IF="interfaces"] # racgvip delete vip_name
复制

可以看到racgvip定义了一些操作来完成对VIP的管理工作,基本上Oracle对VIP会进行以下的操作:

启动:使用ifconfig将VIP绑定到公网对应的网卡上。

检查:检查VIP是否绑定到了对应的网卡上,而且能够ping通;检查公网网卡是否正常;检查是否能够ping通公网所在的默认网关。

停止:使用ifconfig命令将VIP从公网对应的网卡上移除。

以下是VIP资源的一些属性。

[oracle@test1 ~]$ crs_stat -p ora.test1.vip NAME=ora.test1.vip …… DESCRIPTION=CRS application for VIP on a node …… USR_ORA_IF=eth0 …… USR_ORA_NETMASK=255.255.255.0 …… USR_ORA_VIP=*.*.*.*
复制

其中:

USR_ORA_IF:这个属性指定了VIP所在的网卡名。

USR_ORA_NETMASK:指定了VIP对应的子网掩码(netmask)。

USR_ORA_VIP:指定了VIP对应的IP地址。

或者也可以使用下面的命令了解VIP的信息。

[oracle@test1 ~]$ srvctl config nodeapps -n test1 -a VIP exists.: /test1-vip/*.*.*.*/255.255.255.0/eth0
复制
② 数据库实例资源和数据库资源(ora.<数据库名>.<实例名>.inst和ora.<数据库名>.db)

对于数据库资源,实际上它是由数据库实例资源(.inst)和数据库资源(.db)组合而成的。

其中,每个数据库实例会有对应的实例资源进行管理,而数据库资源实际上相当于一个占位资源。

换句话说,当集群中只要有一个节点启动了数据库实例,.db资源就会处于online状态,表示该集群上有正在运行的实例。

对于数据库实例资源,CRS通过racgmdb模块来对数据库实例进行启动、检查和停止操作。

另外,Oracle会为每个数据库实例启动一个racgimon守护进程来监控数据库实例的健康状况。

[oracle@test1 racg]$ ps -ef | grep racg oracle 11284 1 0 Nov19 ? 00:00:04 /u01/app/database/bin/racgimon daemon ora.test1.ASM1.asm oracle 11357 1 0 Nov19 ? 00:01:41 /u01/app/database/bin/racgimon startd ora10g
复制

从数据库层面,racgimon体现为一些数据库进程。

SQL> select program from v$session where program like '%racg%'; PROGRAM ------------------------------------------------ racgimon@test1.cn.oracle.com (TNS V1-V3) racgimon@test1.cn.oracle.com (TNS V1-V3) racgimon@test1.cn.oracle.com (TNS V1-V3) racgimon@test1.cn.oracle.com (TNS V1-V3)
复制

换句话说,这些数据库会话负责搜集数据库实例的健康状况和一些统计信息(例如:每个数据库服务的工作负载信息)。
下面我们来看一下CRS会记录数据库相关的哪些信息并将其用于管理数据库实例。

[oracle@test1 racg]$ srvctl config database -d ora10g -a test1 ora10g1 /u01/app/database test2 ora10g2 /u01/app/database DB_UNIQUE_NAME: ora10g DB_NAME: ora10g ORACLE_HOME: /u01/app/database SPFILE: +DATA/ora10g/spfileora10g.ora DOMAIN: null DB_ROLE: null START_OPTIONS: null POLICY: AUTOMATIC ENABLE FLAG: DB ENABLED
复制

从代码中可以看到:

1)该数据库包含了两个实例,实例1(ora10g1)运行在节点test1上,实例2(ora10g2)运行在test2上。

2)Oracle home位置:/u01/app/database。

3)DB_UNIQUE_NAME:ora10g,使用DB_UNIQUE_NAME的主要原因是为了在DataGuard环境下区分主库和备库。

4)SPFILE:+DATA/ora10g/spfileora10g.ora,数据库的初始化参数文件位置。

5)DB_ROLE定义了数据库的角色,如果是在DataGuard环境下,最好是将其设置成为PRIMARY或STANDBY。

③ ASM资源(ora.<节点名>.<ASM实例名>.asm)

ASM资源,顾名思义就是为了ASM实例所设计的。

CRSD通过这个资源来管理ASM实例,每个节点都会有一个ASM资源对应本地节点的ASM实例。

CRSD管理ASM实例的方式和管理数据库的方式基本上是一样的,当然,由于ASM并没有真正的物理数据库资源,所以不会有.db资源与之对应。

CRSD会启动对应的racgimon守护进程来检查ASM实例的健康性。

[oracle@test1 racg]$ ps -ef | grep racg
oracle 7584  4371  0 08:02 pts/3    00:00:00 grep racg
oracle  11284 1  0 Nov19 ? 00:00:04 /u01/app/database/bin/racgimon daemon ora.test1.ASM1.asm
oracle 11357 1  0 Nov19 ? 00:01:42 /u01/app/database/bin/racgimon startd ora10g
复制

对于ASM实例,是不会有racgimon会话存在的。

以下是一个srvctl命令的输出:

[oracle@test1 racg]$ srvctl config asm -n test1 +ASM1 /u01/app/database
复制

可以看到CRSD主要记录了ASM所在的Oracle主目录和对应的ASM实例名。

④监听程序(listener)资源(ora.<节点名>.<监听程序名>.lsnr)

该资源负责管理集群的监听程序资源,这个资源比较简单,RACG模块会通过命令lsnrctl start来启动监听程序资源;用lsnrctl stop来停止监听程序资源;用lsnrctl status来检查监听程序资源的状态。

事实上CRSD只需要记录监听程序的名称就可以了,而对于监听的位置、协议和端口等信息,是从<oracle_home>/network/admin/listener.ora文件中获得的。

换句话说,监听程序和系统是不是RAC没有关系,它实现的功能与单实例数据库系统是一样的。

唯一的区别就是:RAC系统中listener资源需要依赖于VIP资源,也就是说,当本地节点的VIP资源漂移到其他节点后,本地节点的监听程序资源会被离线掉。

监听程序资源是不可能随着VIP资源漂移到其他节点的,因为listener不可能监听远程节点的地址。

因此,我们能看到以下的srvctl命令只列出了节点名和监听程序名称。

[oracle@test1 dbs]$ srvctl config listener -n test1 test1 LISTENER_TEST1
复制
⑤ONS资源(ora.<节点名>.ons)

ONS是Oracle Notification Service的缩写,而ONS资源就是负责管理这个服务的。

ONS的主要功能是配合本地的EVMD和racgimon模块向集群中的应用程序发布集群事件。

对于ONS,它的配置信息来自于文件<oracle_home>/opmn/conf/ons.config。以下是一个示例ons.config文件,其中包含了常用的配置参数:

localport=6200 remoteport=6200 loglevel=3 useocr=on
复制

其中:

localport:表示本地节点ONS发布事件的端口。

remoteport:表示本地节点用于监听其他节点发布事件的端口。

loglevel:表示调试日志产生的级别。

useocr:表示是否使用OCR中记录的ONS信息。

在ONS配置结束之后,可以已使用onsctl工具对ONS进行操作。

示例1:检查ONS状态。

[oracle@test1 opmn]$ onsctl ping Number of configuration nodes retrieved: 2 0: {node = test1,port = 6200} Adding remote host test1:6200 1: {node = test2,port = 6200} Adding remote host test2:6200 ons is running ...
复制

以上信息说明ONS正在运行。

示例2:查看ONS的详细信息。

[oracle@test1 conf]$ onsctl debug Number of configuration nodes retrieved: 2 0: {node = test1,port = 6200} Adding remote host test1:6200 1: {node = test2,port = 6200} Adding remote host test2:6200 HTTP/1.1 200 OK Content-Length: 1282 Content-Type: text/html Response: ======== ONS ======== Listeners: NAME BIND ADDRESS PORT FLAGS SOCKET ------- --------------- ----- -------- ------ Local 127.000.000.001 6113 00000142 7 Remote 010.182.208.036 6200 00000101 8 Request No listener Server connections: ID IP PORT FLAGS SENDQ WORKER BUSY SUBS ---------- --------------- ----- -------- ---------- -------- ------ ----- 1 010.182.208.037 6200 00010005 0 1 0 Client connections: ID IP PORT FLAGS SENDQ WORKER BUSY SUBS ---------- --------------- ----- -------- ---------- -------- ------ ----- 3 127.000.000.001 6113 0001001a 0 1 0 Pending connections: ID IP PORT FLAGS SENDQ WORKER BUSY SUBS ---------- --------------- ----- -------- ---------- -------- ------ ----- 0 127.000.000.001 6200 00020822 0 1 0 Worker Ticket: 3/3,Idle: 360 THREAD FLAGS -------- -------- b7f25b90 00000012 b7f1db90 00000012 b7f15b90 00000012 Resources: Notifications: Received: 1,in Receive Q: 0,Processed: 1,in Process Q: 0 Pools: Message: 24/25 (1),Link: 25/25 (1),Subscription: 25/25 (1)
复制

ONS资源在11gR2版本中仍然存在,而且作用和10.2版本基本一致。唯一的区别是ons.config文件不再需要手动配置,代理进程会完成对该文件的管理。

⑥ 数据库服务资源(ora.<数据库名>.<服务名>.<实例名>.srv和ora.<数据库名>.<服务名>.cs)

对于10.2版本的集群,数据库服务资源实际上是由.srv和.cs两个资源共同构成的。

其中.srv称为Service number资源,用来定义对应的数据库服务应该运行在哪个节点上;.cs节点是service资源用来定义资源的其他属性。下面我们通过一个简单的例子,来说明CRSD是如何管理数据库服务资源的。

1)创建一个数据库服务:

[oracle@test2 conf]$ srvctl add service -d ora10g -s test -r ora10g2 -a ora10g1 -P basic [oracle@test2 conf]$ srvctl config service -d ora10g -s test test PREF: ora10g2 AVAIL: ora10g1
复制

其中:

-d指定服务所运行的数据库名;

-s指定数据库服务名称;

-r指定数据库服务默认运行的数据库实例;

-a指定数据库服务的备用实例;

-P指定了TAF的策略。

2)启动服务并查看结果。

[oracle@test2 conf]$ srvctl start service -d ora10g -s test [oracle@test2 conf]$ crs_stat -t Name Type Target State Host ------------------------------------------------------------ …… ora....g2.inst application ONLINE ONLINE test2 ora....test.cs application ONLINE ONLINE test2 ora....0g2.srv application ONLINE ONLINE test2
复制

可以看到对应的.srv资源被启动到了节点test2上,而.cs资源也运行在test2上。

我们再来看实例2的数据库alert.log:

Tue Nov 25 14:44:35 CST 2014 ALTER SYSTEM SET service_names='ora10g','test' SCOPE=MEMORY SID='ora10g2';
复制

事实上CRSD连接到了数据库当中并运行了上面的命令,为实例2添加了服务test。

3)将数据库实例终止,并看一看结果。

+实例2:

[oracle@test2 bdump]$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.5.0 - Productionon Tue Nov 25 145055 2014 Copyright (c) 19822010,Oracle. All Rights Reserved. Connected toOracle Database 10g Enterprise Edition Release 10.2.0.5.0 - Production With the Partitioning,Real Application Clusters,OLAP,Data Mining and Real Application Testing options SQL> shutdown abort ORACLE instance shut down.
复制

+实例1:

[oracle@test1 logs]$ crs_stat -t Name Type Target State Host ------------------------------------------------------------ …… ora....g2.inst application OFFLINE OFFLINE ora....test.cs application ONLINE ONLINE test2 ora....0g2.srv application ONLINE ONLINE test1
复制

可以看到,实例2已经被终止,.cs资源继续运行在节点test2上,而.srv资源已经切换到了节点test1上。
再来看一下实例1的数据库alert.log:

Tue Nov 25 14:53:28 CST 2014 ALTER SYSTEM SET service_names='ora10g','test' SCOPE=MEMORY SID='ora10g1';
复制

事实上CRSD连接到了实例1当中并运行了上面的命令,为实例1添加了服务test。

即使实例2恢复运行,数据库服务也不会切换回原有的实例。

4)手动终止服务。

[oracle@test2 bdump]$ srvctl stop service -d ora10g -s test [oracle@test2 bdump]$ crs_stat -t Name Type Target State Host ------------------------------------------------------------ …… ora....g1.inst application ONLINE ONLINE test1 ora....g2.inst application ONLINE ONLINE test2 ora....test.cs application OFFLINE OFFLINE ora....0g2.srv application OFFLINE OFFLINE
复制

可以看到,.cs和.srv资源会同时被离线。

再来看一下对应的数据库alert.log:

Tue Nov 25 15:01:58 CST 2014 ALTER SYSTEM SET service_names='ora10g' SCOPE=MEMORY SID='ora10g1';
复制

手动停止数据库服务资源后,通过该服务连接到数据库的会话会被终止。

从上面的测试过程大家可以看到,CRSD是通过在对应的数据库实例中修改参数service_names的方式来管理数据库服务资源的。而对于资源的检查工作,是由racgimon来完成的。

2. 11gR2版本

由于10gR2版本对资源的管理来说并不是很完善,所以,Oracle在11gR2版本的集群中推出了新的资源管理架构——agent。接下来作者会详细介绍这个11gR2版本中的集群新组件。

在11gR2版本的集群中,除了ohasd,其他的一切守护进程和资源都被称之为资源,包括crsd.bin守护进程也会以ora.crsd初始化资源的形式存在,而每一个资源都会被对应的agent(代理进程)所管理,初始化资源和代理进程的关系已在第3章介绍过,这里就不再重复。每个代理进程会根据需要被启动,并管理自己的资源。

资源和代理进程的关系可以参考下面的表格。

image.png

如果GI和数据库软件都使用了Oracle用户安装的话,上面表格中的拥有者为grid用户的资源,会由Oracle用户拥有。

(1)资源管理框架的基本概念

下面我们对agent相关的一些基本概念进行讲解。

EP(Entry Point):它非常类似于10g2R版本中CRSD对应资源的动作,用于指定agent可对这个资源执行哪些操作/动作,支持的EP有:

Start:启动资源。

Stop:停止资源。

Check:检查资源的状态,如果发现资源状态改变,agent则会通知GI资源状态发生了改变。

Clean:清理资源,一般来说清理资源会在资源存在问题而需要重新启动或failover之前发生。

Abort:中止资源。

状态:当资源进入了某一个EP后,一定会返回一个状态,支持的状态有:

ONLINE:在线。对应资源的online状态。

OFFLINE:离线。对应资源的offline状态。当然,即使资源被离线,GI仍然会探测这个资源的状态,以便在资源恢复正常时能够自动将资源重新上线。

UNKNOWN:未知,对应资源的unknown状态。在这种状态下,agent会继续对该资源进行检查。

PARTIAL:资源部分在线,对应资源的intermediate状态。在这种情况下agent会继续对该资源进行检查,并及时更新资源状态。

FAILED:失败。该返回值说明资源存在问题,不能正常工作,agent会首先执行Clean EP,之后根据资源的相关属性进行failover或restart操作。

INTERMEDIAT:资源正处于一个状态到另一个状态之间的中间状态。这说明agent目前还不知道这个资源的状态,但是这个资源的确还在继续向前,或者该资源的确在线但是并没有在自己应该在的节点上。

agent(代理进程):agent只能被ohasd或CRSD启动。其中ohasd启动的agent负责管理集群的初始化资源;CRSD启动的agent负责管理集群的应用程序资源。ohasd和CRSD根据资源的不同会启动不同的agent,有些agent是由root用户启动的,有些是由grid用户启动,还有些是由Oracle用户启动的。agent是高可用的进程,也就是说当agent由于某些原因崩溃之后会有新的agent被启动以继续完成工作。同时agent也是多线程的进程。以下命令的输出显示了几个集群中的所有agent进程。

[grid@rac1 bin]$ ps -ef | grep agent grid 3293 1 0 05:22 00:00:22 /u01/11.2.0/grid/bin/oraagent.bin root 3327 1 1 05:22 00:00:30 /u01/11.2.0/grid/bin/orarootagent.bin root 3375 1 0 05:22 00:00:07 /u01/11.2.0/grid/bin/cssdagent root 3901 1 1 05:24 00:00:26 /u01/11.2.0/grid/bin/orarootagent.bin grid 3905 1 0 05:24 00:00:17 /u01/11.2.0/grid/bin/oraagent.bin grid 4042 1 0 05:24 00:00:02 /u01/11.2.0/grid/bin/scriptagent.bin oracle 4370 1 1 05:24 00:00:26 /u01/11.2.0/grid/bin/oraagent.bin [grid@rac1 bin]$ ps -ef | grep monitor root 3355 1 0 05:22 00:00:08 /u01/11.2.0/grid/bin/cssdmonitor
复制

可以看到启动agent的操作系统用户有oracle、grid以及root。

PE(Policy Engine):由于CRSD是一个分布式的集群组件,也就是说集群中的每一个节点都会运行该组件,而且它们要对一些共享的资源进行管理,所以在对资源进行管理时需要一种协调机制以保证操作能够被顺序执行。

Oracle采用的是主从模式,或者称为master-slave模式。集群中的一个节点(通常,最先启动CRSD的节点)会被选择成为PE的主节点(PE master),集群中所有对资源的操作都会先被发送给PE主节点的CRSD守护进程,再由这个主节点统一发送给需要执行相关操作的节点的agent。

而为了实现这种协调机制,CRSD需要不同的模块协调工作(CRSD同时也是由多个模块构成的),其中比较常见的模块有:

PE模块:主要负责制定CRSD的策略决定。

agent模块:负责和代理进程(agent)进行通信并完成对具体资源的操作。

UI(User Interface)模块:负责响应客户端发送的请求,并和底层的PE模块、agent模块通信。

OCR模块:当操作需要对OCR进行操作时,该模块负责完成对OCR的操作。

通告模块:由于有些操作会导致资源状态的变化,这个模块负责向外发布资源的变化信息,其他的集群组件(例如EVMD)需要接收这些通告。

通信模块:负责节点间CRSD通信。

读者可以通过下面的命令来找到所有的CRSD模块列表:

[root@test1 bin]# ./crsctl lsmodules crs List CRSD Debug Module: AGENT List CRSD Debug Module: AGFW List CRSD Debug Module: CLSFRAME List CRSD Debug Module: CLSVER List CRSD Debug Module: CLUCLS List CRSD Debug Module: COMMCRS List CRSD Debug Module: COMMNS List CRSD Debug Module: CRSAPP List CRSD Debug Module: CRSCCL List CRSD Debug Module: CRSCEVT List CRSD Debug Module: CRSCOMM …… List CRSD Debug Module: OCRRAW List CRSD Debug Module: OCRSRV List CRSD Debug Module: OCRUTL List CRSD Debug Module: SuiteTes List CRSD Debug Module: UiServer
复制

资源类型:由于CRSD需要管理很多资源,所以它把资源分成了很多类型,每一种类型的资源都会有一些共同的资源属性。比较常见的资源类型有:

ora.diskgroup.type:磁盘组相关的资源。

ora.listener.type:监听程序相关的资源。

ora.asm.type:ASM实例相关的资源。

ora.database.type:数据库相关的资源。

资源属性:每个资源都会有相关的属性被定义,agent在对资源进行操作时需要具体的资源属性以决定对资源执行哪些具体操作。资源属性可以分为只读属性、资源特定的属性、可修改属性等。

资源依赖关系:依赖关系,顾名思义就是资源和资源之间的彼此依存关系。在10g版本集,资源依赖关系主要靠资源属性

REQUIRED_RSOURCE来决定。

在11gR2版本的集群上,Oracle对资源依赖关系做了非常详细的区分,它会以资源属性START_DEPENDENCIES和STOP_DEPENDENCIES的形式存在,也就是说,存在两种依赖关系:启动依赖关系和停止依赖关系。

其中,START_DEPENDENCIES在启动资源时起作用,STOP_DEPENDENCIES在关闭资源时启动。例如:以下命令显示了数据库资源和其他资源之间的依赖关系:

[root@rac1 bin]# ./crsctl stat res ora.ora11g.db -p NAME=ora.ora11g.db TYPE=ora.database.type …… START_DEPENDENCIES=hard(ora.DATA.dg) weak(type:ora.listener.type,global:type:ora.scan_listener.type,uniform:ora.ons,global:ora.gns) pullup(ora.DATA.dg) …… STOP_DEPENDENCIES=hard(intermediate:ora.asm,shutdown:ora.DATA.dg) STOP_TIMEOUT=600 ……
复制

这看起来好像很复杂,接下来作者解释一下资源依赖关系是如何实现的。

1)START_DEPENDENCIES:它的格式是START_DEPENDENCIES=<依赖关系类型>(<资源类型>:(资源))。

相应的依赖关系类型可以是hard、weak、pull-up、attraction和dispersion。此处只对前两种进行介绍,因为后三种在实际处理问题时用到的情况很少。

hard(强):强依赖关系是指如果依赖资源要启动的话,被依赖的资源一定已经被启动了。例如:资源A对资源B有强依赖关系,这意味着如果资源A需要启动,资源B必须已经启动成功。结合上面的数据库资源的输出可以看到,数据库资源对磁盘组资源ora.DATA.dg有强依赖关系,这说明在启动数据库时,磁盘组资源ora.DATA.dg必须已经被启动,换句话说,就是磁盘组DATA必须已经被mount了。

weak(弱):弱依赖关系是指如果依赖资源需要启动的话,被依赖的资源也会被启动。但是被依赖资源是否启动成功对依赖资源的启动是没有影响的。例如:资源A对资源B有弱依赖关系,这意味着启动资源A的时候也会尝试启动资源B,但是启动资源B的结果不会影响资源A的启动结果。结合上面的数据库资源的输出可以看到,数据库资源和监听程序资源类型ora.listener.type有弱依赖关系,这说明在启动数据库资源时,监听程序类型的资源也会被启动,但是后者启动的结果不会影响数据库资源的启动。

2)STOP_DEPENDENCIES:它的格式是STOP_DEPENDENCIES=<依赖关系类型>(<资源状态>:(资源))。这种依赖关系只有hard(强)一种,而强依赖关系的含义实际上和START_DEPENDENCIES的含义基本是相同的。

结合上面数据库资源的例子,可以看到它的STOP_DEPENDENCIES是hard(intermediate:ora.asm,shutdown:ora.DATA.dg),含义是:如果ora.asm资源处于intermediate或者offline状态,那么数据库资源就需要被关闭。

如果ora.DATA.dg资源处于shutdown状态(或者说磁盘组被卸载),那么数据资源就需要被关闭。

OCR主节点:这部分和10g版本集群是相同的。

(2)CRSD运行方式

image.png

步骤1:在请求节点的客户端发出请求,例如:一个crsctl命令。

步骤2:请求节点CRSD的UI模块收到对应的请求,并将请求发送给本地节点CRSD的PE模块。

步骤3:本地节点的PE模块在分析了请求所需要执行的操作之后,将该请求发送给PE主节点的PE模块。

步骤4:PE主节点上的PE模块在分析了收到的请求后,将需要执行的操作发送给了目标节点的agent模块。

步骤5:目标节点的agent模块通知本地节点上对应的agent进程对资源进行操作。

步骤6:目标节点的agent完成了对资源的操作,并通知本地节点的agent模块。

步骤7:目标节点的agent模块将结果返回给PE主节点的PE模块。

步骤8:PE主节点的PE模块将返回结果发送给请求节点PE模块。

步骤9:请求节点的PE模块将命令的返回结果发送给本节点的UI模块。

步骤10:请求节点的UI模块将请求结果发送给对应的客户端。

如果大家对RAC的内存融合技术比较熟悉的话,这个过程时间实际上和内存融合技术是比较相似的。

下面作者通过一个实际的例子和对应的crsd.log日志文件向大家说明之前的步骤。需要说明的是,作者在此使用的测试环境是一个双节点的集群,所以PE主节点和请求节点或者目标节点可能是重复的。

(1)在节点1上终止节点2的监听程序资源

[grid@rac1 ~]$ date; srvctl stop listener -n rac2 -l LISTENER Sat Nov 22 07:14:48 CST 2014
复制

(2)节点1的crsd.log

2014-11-22 06:58:46.291: [CRSPE][2936642448] {1:20337:2} PE MASTER NAME: rac1 <<<<<<< 2014-11-22 06:58:46.291: [CRSPE][2936642448] {1:20337:2} Starting to read configuration 2014-11-22 06:58:46.351: [CRSPE][2936642448] {1:20337:2} Reading (1) servers
复制

可以看到节点1是PE的主节点(PE MASTER)。

…… 2014-11-22 07:14:50.225: [CRSPE][2936642448] {1:20337:179} Expression Filter : (((NAME == ora.LISTENER.lsnr) AND ((STATE != OFFLINE) OR (TARGET != OFFLINE))) AND (LAST_SERVER == rac2)) 2014-11-22 07:14:50.252: [UiServer][2932439952] CS(0xc2e77e0)set Properties ( grid,0xc22f438) 2014-11-22 07:14:50.264: [UiServer][2934541200] {1:20337:180} Container [Name: UI_STOP <<<<<< API_HDR_VER: TextMessage[2] CLIENT: TextMessage[] CLIENT_NAME: TextMessage[/usr/bin/java] CLIENT_PID: TextMessage[5234] CLIENT_PRIMARY_GROUP: TextMessage[oinstall] FILTER: TextMessage[(^A(^A(^ANAME^A==^Aora.LISTENER.lsnr^A)^A&&^A(^A(^ASTATE^A!=^AOFFLINE^A)^A||^A(^ATARGET^A!=^AOFFLINE^A)^A)^A)^A&&^A(^ALAST_SERVER^A==^Arac2^A)^A)] FILTER_TAG: TextMessage[1] LOCALE: TextMessage[AMERICAN_AMERICA.US7ASCII] QUEUE_TAG: TextMessage[1] ] 2014-11-22 07:14:50.264: [UiServer][2934541200] {1:20337:180} Sending message to PE. ctx= 0xb0b007c8,Client PID: 5234 <<<<<
复制

可以看到UI服务器在收到了客户端发送的srvctl命令之后,开始准备终止节点2的监听程序资源,并将请求发送给PE模块。

2014-11-22 07:14:50.266: [CRSPE][2936642448] {1:20337:180} Processing PE command id=219. Description: [Stop Resource : 0xc287030] 2014-11-22 07:14:50.271: [CRSPE][2936642448] {1:20337:180} Expression Filter : (((NAME == ora.LISTENER.lsnr) AND ((STATE != OFFLINE) OR (TARGET != OFFLINE))) AND (LAST_SERVER == rac2)) 2014-11-22 07:14:50.274: [CRSPE][2936642448] {1:20337:180} Expression Filter : (((NAME == ora.LISTENER.lsnr) AND ((STATE != OFFLINE) OR (TARGET != OFFLINE))) AND (LAST_SERVER == rac2)) 2014-11-22 07:14:50.279: [CRSPE][2936642448] {1:20337:180} RI [ora.LISTENER.lsnr rac2 1] new target state: [OFFLINE] old value: [ONLINE] 2014-11-22 07:14:50.280: [CRSOCR][2945047440] {1:20337:180} Multi Write Batch processing... 2014-11-22 07:14:50.283: [CRSPE][2936642448] {1:20337:180} RI [ora.LISTENER.lsnr rac2 1] new internal state: [STOPPING] old value: [STABLE] 2014-11-22 07:14:50.284: [CRSPE][2936642448] {1:20337:180} Sending message to agfw: id = 857 2014-11-22 07:14:50.294: [CRSPE][2936642448] {1:20337:180} CRS-2673: Attempting to stop 'ora.LISTENER.lsnr' on 'rac2' 2014-11-22 07:14:50.296: [UiServer][2934541200] {1:20337:180} Container [ Name: ORDER MESSAGE: TextMessage[CRS-2673: Attempting to stop 'ora.LISTENER.lsnr' on 'rac2'] MSGTYPE: TextMessage[3] OBJID: TextMessage[ora.LISTENER.lsnr rac2 1] WAIT: TextMessage[0] ]
复制

由于在本测试中PE主节点就是请求节点,所以,大家可以看到本地的PE模块马上会停止节点2(rac)上的监听程序资源操作。同时发送消息给节点2的agent模块。

(3)节点2的crsd.log

2014-11-22 07:14:50.357: [AGFW][2953784208] {1:20337:180} Agfw Proxy Server received the message: RESOURCE_STOP[ora.LISTENER.lsnr rac2 1] ID 4099:857 2014-11-22 07:14:50.357: [AGFW][2953784208] {1:20337:180} Agfw Proxy Server forwarding the message: RESOURCE_STOP[ora.LISTENER.lsnr rac2 1] ID 4099:857 to the agent /u01/11.2.0/grid/bin/oraagent_grid
复制

可以看到节点2的agent模块收到了停止节点监听程序的消息(RESOURCE_STOP[ora.LISTENER.lsnr rac2 1])后,将这个请求转发给了对应的agent进程。

(4)节点2的agent.log(<gi_home>/log/rac2/agent/crsd/oraagent_grid.log)

2014-11-22 07:14:50.366: [AGFW][2766560144] {1:20337:180} Agent received the message: RESOURCE_STOP[ora.LISTENER.lsnr rac2 1] ID 4099:571 2014-11-22 07:14:50.366: [AGFW][2766560144] {1:20337:180} Preparing STOP command for: ora.LISTENER.lsnr rac2 1
复制

可以看到,节点2对应的代理进程收到了由agent模块发送过来的消息,开始准备停止监听程序资源。

2014-11-22 07:14:50.366: [AGFW][2766560144] {1:20337:180} ora.LISTENER.lsnr rac2 1 state changed from: ONLINE to: STOPPING 2014-11-22 07:14:50.369: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00108:) clsn_agent::stop { 2014-11-22 07:14:50.369: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] LsnrAgent::stop { 2014-11-22 07:14:50.369: [USRTHRD][2662325136] {1:20337:180} Thread:RegEndpointThread:LISTENER stop { 2014-11-22 07:14:50.370: [USRTHRD][2494532496] {1:20337:180} Thread:RegEndpointThread:LISTENER isRunning is reset to false here 2014-11-22 07:14:50.371: [USRTHRD][2662325136] {1:20337:180} Thread:RegEndpointThread:LISTENER stop } 2014-11-22 07:14:50.371: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] lsnrctl stop LISTENER
复制

监听程序资源正在被停止。

2014-11-22 07:14:50.371: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] getOracleHomeAttrib: oracle_home = /u01/11.2.0/grid 2014-11-22 07:14:50.372: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] getOracleHomeAttrib: oracle_home = /u01/11.2.0/grid 2014-11-22 07:14:50.373: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] Utils::getCrsHome crsHome /u01/11.2.0/grid 2014-11-22 07:14:50.373: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] Utils::execCmd 1 USR_ORA_ENV:ORACLE_BASE=/u01/app/oracle oracleHome:/u01/11.2.0/grid CrsHome:/u01/11.2.0/grid 2014-11-22 07:14:50.373: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] Utils::getCrsHome crsHome /u01/11.2.0/grid 2014-11-22 07:14:50.373: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] Adding Environment Variables ORACLE_HOME=/u01/11.2.0/grid 2014-11-22 07:14:50.373: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] Adding Environment Variables TNS_ADMIN=/u01/11.2.0/grid/network/admin/ 2014-11-22 07:14:50.373: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] Adding Environment variable from USR_ORA_ENV ORACLE_BASE=/u01/app/oracle 2014-11-22 07:14:50.373: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] Utils:execCmd action = 2 flags = 38 ohome = (null) cmdname = lsnrctl. 2014-11-22 07:14:50.373: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] getOracleHomeAttrib: oracle_home = /u01/11.2.0/grid 2014-11-22 07:14:50.487: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:) 2014-11-22 07:14:50.487: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:)LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 22-NOV-2014 07:14:50 2014-11-22 07:14:50.487: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:) 2014-11-22 07:14:50.487: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:)Copyright (c) 1991,2011,Oracle. All rights reserved. 2014-11-22 07:14:50.487: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:) 2014-11-22 07:14:50.487: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:)Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER))) 2014-11-22 07:14:50.487: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:) 2014-11-22 07:14:50.589: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:)The command completed successfully 2014-11-22 07:14:50.589: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00010:) 2014-11-22 07:14:50.590: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] execCmd ret = 0 2014-11-22 07:14:50.590: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] LsnrAgent::stop } 2014-11-22 07:14:50.590: [ora.LISTENER.lsnr][2662325136] {1:20337:180} [stop] (:CLSN00108:) clsn_agent::stop } 2014-11-22 07:14:50.590: [AGFW][2662325136] {1:20337:180} Command: stop for resource: ora.LISTENER.lsnr rac2 1 completed with status: SUCCESS
复制

监听程序资源被成功终止。

2014-11-22 07:14:50.655: [AGFW][2766560144] {1:20337:180} Agent sending reply for: RESOURCE_STOP[ora.LISTENER.lsnr rac2 1] ID 4099:571 2014-11-22 07:14:50.656: [AGFW][2766560144] {1:20337:180} ora.LISTENER.lsnr rac2 1 state changed from: STOPPING to: OFFLINE 2014-11-22 07:14:50.656: [AGFW][2766560144] {1:20337:180} Agent sending last reply for: RESOURCE_STOP[ora.LISTENER.lsnr rac2 1] ID 4099:571
复制

代理进程向agent模块发送监听程序终止成功消息。

(5)节点2的crsd.log

2014-11-22 07:14:50.662: [AGFW][2953784208] {1:20337:180} Received the reply to the message: RESOURCE_STOP[ora.LISTENER.lsnr rac2 1] ID 4099:571 from the agent /u01/11.2.0/grid/bin/oraagent_grid
复制

节点2的agent模块收到了代理进程发送的消息。

2014-11-22 07:14:50.662: [AGFW][2953784208] {1:20337:180} Agfw Proxy Server sending the reply to PE for message:RESOURCE_STOP[ora.LISTENER.lsnr rac2 1] ID 4099:857
复制

节点2的agent模块向PE主节点发送监听程序终止成功消息。

(6)节点1的crsd.log

2014-11-22 07:14:50.599: [CRSPE][2936642448] {1:20337:180} Received reply to action [Stop] message ID: 857 2014-11-22 07:14:50.606: [CRSPE][2936642448] {1:20337:180} Received reply to action [Stop] message ID: 857 2014-11-22 07:14:50.606: [CRSPE][2936642448] {1:20337:180} RI [ora.LISTENER.lsnr rac2 1] new internal state: [STABLE] old value: [STOPPING] 2014-11-22 07:14:50.606: [CRSPE][2936642448] {1:20337:180} RI [ora.LISTENER.lsnr rac2 1] new external state [OFFLINE] old value: [ONLINE] label = [] 2014-11-22 07:14:50.606: [CRSPE][2936642448] {1:20337:180} CRS-2677: Stop of 'ora.LISTENER.lsnr' on 'rac2' succeeded 2014-11-22 07:14:50.607: [CRSPE][2936642448] {1:20337:180} PE Command [ Stop Resource : 0xc287030 ] has completed
复制

可以看到节点1的PE模块收到了对应的消息,并确认节点2的监听程序资源已经被停止。

2014-11-22 07:14:50.607: [CRSPE][2936642448] {1:20337:180} UI Command [Stop Resource : 0xc287030] is replying to sender. 2014-11-22 07:14:50.610: [CRSRPT][2934541200] {1:20337:180} Published to EVM CRS_RESOURCE_STATE_CHANGE for ora.LISTENER.lsnr 2014-11-22 07:14:50.610: [UiServer][2934541200] {1:20337:180} Container [ Name: ORDER MESSAGE: TextMessage[CRS-2677: Stop of 'ora.LISTENER.lsnr' on 'rac2' succeeded] MSGTYPE: TextMessage[3] OBJID: TextMessage[ora.LISTENER.lsnr rac2 1] WAIT: TextMessage[0] ] 2014-11-22 07:14:50.611: [UiServer][2934541200] {1:20337:180} Container [ Name: UI_DATA ora.LISTENER.lsnr rac2 1: TextMessage[0] ] 2014-11-22 07:14:50.611: [UiServer][2934541200] {1:20337:180} Done for ctx=0xb0b007c8
复制

最后,节点1上的UI模块向客户端发送消息说监听程序被成功停止。同时向EVM发送消息,以便对应的集群事件订阅者能够收到“节点2监听程序终止”的集群事件。

通过上面的例子,大家实际上也能够看到,作者使用的CRSD日志中有一部分实际上是由三个数字构成的,而这三个数字实际上是可以帮助我们唯一标识CRSD事件的一个方式,Oracle称之为tint。大家可以看到,在上面的例子当中,无论是crsd.log还是agent.log,与停止节点2监听程序资源相关的日志都具有唯一的tint标识{1:20337:180},其中,第一个数字代表事件发起的节点;第二个数字是一个进程编号;第三个数字是一个单向增长的数字,能够标识事件的标号。由于11gR2版本集群中CRSD层面的日志产生得很快,记住各个唯一标识CRSD事件的方式在诊断CRSD层面的问题时是很有帮助的,它能够使我们迅速找到和某一个事件相关的CRSD、agent日志文件中的内容。

(3)CRSD管理的新资源

CRSD管理的资源基本上可以分为两种:本地资源和集群资源。

本地资源:是指该资源只能在本地节点上运行,不能转移到集群的其他节点上运行。本地资源包括:network资源、GSD资源、监听程序资源、ONS资源、ASM代理资源和磁盘组资源。

集群资源:是指该资源会选择在集群的某一个或多个节点上运行,当某个节点出现问题时,资源可以切换到集群中的其他节点上继续运行。集群资源包括:VIP资源、SCAN VIP资源、GNS资源、数据库资源和数据库服务资源。

下面我们就开始分别介绍11gR2版本集群中CRSD管理的新资源。

(1)network资源

这个资源用于管理集群的公网。其中有一项定义了集群的公网,例如:<gpnp:Network id="net1"IP="192.168.56.0"Adapter="eth0"Use=“public”/>。

从11gR2版本开始,用户可以根据自已的需要为集群定义多个网络资源(或者叫作公网资源),它们会以ora.net.network资源的形式存在,其中n从1开始,表示集群默认的公网。

之后,在每个网络资源下定义相应的VIP资源,以便客户端能够通过这些VIP资源连接到对应的应用程序上面。

CRSD会通过网络资源的网卡信息和相应的子网信息对网络资源进行管理,下面来看一下network资源的基本属性。

[grid@rac1 crsd]$ crsctl stat res ora.net1.network -p NAME=ora.net1.network TYPE=ora.network.type ACL=owner:root:rwx,pgrp:root:r-x,other::r--,group:oinstall:r-x,user:grid:r-x …… AGENT_FILENAME=%CRS_HOME%/bin/orarootagent%CRS_EXE_SUFFIX% ALIAS_NAME= AUTO_START=restore …… DEGREE=1 DESCRIPTION=Oracle Network resource ENABLED=1 …… USR_ORA_AUTO=static USR_ORA_ENV= USR_ORA_IF=eth0 USR_ORA_NETMASK=255.255.255.0 USR_ORA_SUBNET=192.168.56.0 VERSION=11.2.0.3.0
复制

其中:

NAME表示资源名称。

TYPE表示资源类型。

ACL=owner:root:rwx,pgrp:root:r-x,other::r–,group:oinstall:r-x,user:grid:r-x说明了资源的所有者、group以及权限信息,这部分信息实际上和Linux系统的文件属性、权限是类似的。

AGENT_FILENAME定义了管理该资源的agent。公网资源是由orarootagent管理的。

AUTO_START表示该资源是否需要自动启动,它可以取以下3个值之一:

1)never:资源不会随着集群启动而被自动启动。

2)always:资源永远会随着集群启动而被自动启动。

3)restore:参照资源在集群关闭前的状态决定集群在重新启动后是否被自动启动。

DEGREE定义了在一个节点上可以启动几个这种资源,1表示每个节点只能有1个ora.net1.network资源存在。

USR_ORA_IF定义了资源所运行的网卡。本例为eth0,表示该网络资源运行在网卡eth0上。

USR_ORA_NETMASK定义了资源的子网掩码(Net Mask)信息。

USR_ORA_SUBNET定义了资源的子网信息,本例为192.168.56.0,表示该资源所在的子网为192.168.56.0。

需要说明的是,由于这个资源管理着集群的公网,很多资源都需要依赖于这个资源,例如:VIP资源、SCAN VIP资源、监听程序资源、CVU资源、数据库服务资源。一旦这个资源出现了问题,依赖于这个资源的其他资源都会被离线。

(2)VIP资源

11gR2版本的集群中,一共有4种类型的VIP资源:

1)节点VIP资源(ora.<节点名>.vip):该资源和10gR2版本的VIP资源功能是相同的。

2)SCAN VIP资源(ora.scan<1-3>.vip):该资源用于管理集群的SCAN对应的IP地址。作者会在第13章中详细介绍SCAN的内容。

3)GNS VIP资源(ora.gns.vip):GNS实际上可以认为是Oracle推出的DNS,在大型网络当中,如果DHCP被使用,GNS可以作为DNS定义的域(Domain)的一个子域(Sub-Domain)存在,为GI中的VIP、SCAN VIP和节点公网IP提供域名解析服务,使GI不再需要固定的IP地址,而是从DHCP租用IP地址。如果需要使用GNS的话,就需要一个GNS VIP地址来定义GNS所在的子域位置。在实际应用中GNS的使用是很少的,读者简单了解就可以了,如果有必要,可从其他的一些相关网站或者博客上详细了解GNS的内容。另外,如果读者阅读了一些12C版本集群的重要新特性Flex cluster相关的资料,或者在实际工作中已经使用了Flex Cluster,那么就需要知道12C Flex Cluster要求用户配置一个固定的GNS VIP地址,以用于启动GNS服务,便于HUB节点将自己的信息注册到GNS上。

4)应用程序VIP(Application VIP)资源:用户可以根据自己的需要创建用户自定义的VIP地址。这种用户自定义的VIP地址的行为与节点VIP是一致的,也可以根据需要切换到集群的其他节点上。

无论以上的哪一种VIP资源,它们都依赖于对应的网络资源。

VIP资源主要的资源属性有:

1)AGENT_FILENAME:定义了管理该资源的代理进程。以上4种VIP资源都是由orarootagent来管理的。

2)START_DEPENDENCIES:定义了该资源的启动依赖关系。以上4种VIP资源都需要依赖于公网资源(ora.net1.network)。

3)STOP_DEPENDENCIES:定义了资源停止依赖关系。以上4种VIP资源都需要依赖于公网资源(ora.net1.network)。

4)USR_ORA_VIP:这里定义了VIP的地址。在默认情况下,上面4种VIP资源会记录VIP地址对应的主机名,GI会根据/etc/hosts文件中的信息将主机名解析成IP地址。

(3)监听程序资源

在11gR2版本的集群中,一共有两种类型的监听程序资源,分别是SCAN监听程序和节点监听程序。监听程序的功能是负责接收通过(SCAN)VIP或者公网IP地址到数据库的连接,并将连接发送给数据库。而监听程序资源的功能实际上就是负责管理监听程序,例如:启动、关闭和监控监听程序的状态。

1)SCAN监听程序:SCAN监听程序需要和SCAN VIP成对出现,负责接受从SCAN VIP到数据库的连接。也就是说,SCAN VIP和对应的SCAN监听程序需要运行在相同节点上,当SCAN VIP切换到其他节点上之后,SCAN监听程序也会随之切换。每个SCAN监听程序只负责监听对应SCAN VIP的IP地址,不会监听其他的IP地址。

2)节点监听程序:节点的监听程序实际上和10gR2版本的监听程序基本是相同的,负责接收通过节点VIP或者公网IP到数据库的连接。另外,11gR2版本的监听程序是通过获取公网的子网信息和OCR中的信息来获得集群的公网IP地址、VIP地址的,这一点和10gR2版本是不同的。

监听程序资源主要的资源属性有:

1)ACTION_SCRIPT:定义了管理监听程序资源时需要运行的脚本,例如:启动监听程序时使用lsnrctl start;检查监听程序状态时使用lsnrctl status。

2)AGENT_FILENAME:定义了管理监听程序资源时使用的agent。监听程序资源是通过oraagent_grid代理进程管理的。

3)ENDPOINTS:定义了监听程序指定的协议和端口号,例如:TCP:1521。

4)ORACLE_HOME:定义了监听程序所运行的oracle_home,默认情况下,监听程序需要从GI主目录启动。

5)START_DEPENDENCIES:定义了该资源的启动依赖关系。监听程序资源需要依赖于对应的VIP资源(ora.<VIP名>.vip)。

(4)ONS资源

ONS资源负责监控Oracle Notification Service的状态。ONS对应的配置文件位于<gi_home>/opmn/config/ons.config.<主机名>中,其中定义了与ONS相关的基本配置参数。

(5)GSD资源

GSD资源的作用是为了向后兼容9i版本的数据库资源,这个资源在默认情况下处于离线状态。换句话说,如果集群中存在运行的9i版本的数据库与软件,那么这个资源需要上线,否者这个资源对集群没有任何作用,应该保持离线。

(6)GNS资源

GNS资源负责为集群提供域名解析服务,它的功能是配合DHCP为集群的公网、VIP、SCAN VIP提供域名解析服务。GNS会以DNS的一个子域存在。由于GNS除了在12C版本集群的Flex Cluster中需要使用外,在其他实际应用中很少使用,所以作者不再过多介绍。

(7)ASM代理资源

由CRSD管理的ASM资源(ora.asm)实际上是OHASD管理的ASM资源的一个代理资源,而OHASD管理的ASM资源才是真正负责管理集群的ASM实例。换句话说,CRSD管理的ASM资源只会显示真正的ASM实例的状态。当然,在ASM实例启动之后,CRSD会通过管理ora.asm资源的代理进程来设置ASM实例的初始化参数local_listener,这也是我们够在lsnrctl status的输出中看到ASM实例被显示出来的原因。例如:

[grid@rac1 ~]$ lsnrctl status LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 23-NOV-2014 09:57:09 Copyright (c) 1991,2011,Oracle. All rights reserved. Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER))) STATUS of the LISTENER ------------------------ Alias LISTENER Version TNSLSNR for Linux: Version 11.2.0.3.0 - Production Start Date 23-NOV-2014 09:52:42 Uptime 0 days 0 hr. 4 min. 27 sec Trace Level off Security ON: Local OS Authentication SNMP OFF Listener Parameter File /u01/11.2.0/grid/network/admin/listener.ora Listener Log File /u01/app/oracle/diag/tnslsnr/rac1/listener/alert/log.xml Listening Endpoints Summary...(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.11)(PORT=1521))) Services Summary... Service "+ASM" has 1 instance(s). Instance "+ASM1",status READY,has 1 handler(s) for this service... Service "ora11g" has 1 instance(s). Instance "ora11g1",status READY,has 1 handler(s) for this service... The command completed successfully
复制

如果我们再仔细思考一下,事实上这种设计是很自然的,接下来是一些简单的解释。

OHASD所管理的资源都是集群的初始化资源,而这些资源都是集群的本地资源,也就是说,这些资源所进行的绝大部分操作都仅限于本地节点。

另外,由于在11gR2版本的集群中,OCR和VF都已经保存到了ASM的磁盘组中,对于ocssd,它可以通过gpnp profile中的VF发现路径(Discovery String)来扫描对应路径下的所有磁盘的头信息,进而发现集群的VF。

但是对于CRSD,它需要在ASM实例启动并且OCR所在的磁盘组被挂载之后才能够访问OCR。与此同时ASM实例本身也作为集群的应用程序之一,需要被集群管理,而负责管理集群应用程序的进程是CRSD。

另外,集群也需要一个CRSD层面的ASM资源来对ASM实例进行一些全局操作,例如:配置local_listener。基于以上的考虑,在11gR2版本的集群中,出现了两个ASM资源:OHASD管理的ASM资源和CRSD管理的ASM资源。前者负责管理本地节点的ASM实例;后者负责反映ASM实例的状态,同时对ASM实例进行一些全局性的操作。

以下是ASM资源的一些属性:

1)AGENT_FILENAME:定义了管理ASM资源的代理进程。该资源是由oraagent_grid管理的。

2)GEN_USR_ORA_INST_NAME@SERVERNAME(<节点名>):定义了每个节点上运行的ASM实例名。

(8)磁盘组资源

磁盘组资源(ora.<磁盘组名>.dg)负责管理对应的ASM磁盘组,该资源在磁盘组被挂载后会自动上线,并开始监控磁盘组的状态。如果某一个使用了该磁盘组的数据库被打开后,CRSD会自动设置数据库资源和磁盘组资源之间的依赖关系(数据库资源对磁盘组资源有强START_DEPENDENCY和STOP_DEENDENCY依赖关系)。

(9)数据库资源

数据库资源(ora.<数据库名>.db)是11gR2版本集群中新增加的资源,它替代了原有的10.2版本中的数据库实例资源和数据库资源。该资源负责管理集群中运行的数据库。11gR2版本的CRSD会在数据库中创建oraagent进程来监控进程并搜集一些统计信息,例如:

SQL> select sid,program from v$session where program like '%ag%'SID PROGRAM ---------- ------------------------------------------------ 32 oraagent.bin@rac2 (TNS V1-V3) 40 oraagent.bin@rac2 (TNS V1-V3) 54 oraagent.bin@rac2 (TNS V1-V3)
复制

下面作者介绍一些数据库资源的属性来说明CRSD是如何管理数据库资源的。

1)AGENT_FILENAME:定义了管理数据库的代理进程(oraagent_oracle)。

2)CARDINALITY:定义了集群中可以同时运行数据库资源的节点数量。

3)DEGREE:定义了每一个节点可以启动多少个该资源对应的实例。

4)GEN_AUDIT_FILE_DEST:定义了数据库的audit文件路径。

5)GEN_START_OPTIONS@SERVERNAME(<节点名>):定义了数据库在对应节点上的启动方式,默认情况下应该为open,代表agent会将数据库启动到open状态;如果该值为nomount,代表agent只会将数据库在该节点上启动到nomount状态。

6)ORACLE_HOME:数据库启动的oracle home路径。

7)ROLE:数据库的角色。如果这个值为PRIMARY,代表这是主库;如果这个值为STANDBY,代表这是备库。

8)SERVER_POOLS:定义该数据库所在的服务器池。

9)SPFILE:定义了数据库的初始化参数文件。

10)START_DEPENDENCIES:定义了数据库资源的启动依赖资源。

11)STOP_DEPENDENCIES:定义了数据库资源的停止依赖资源。

12)USR_ORA_DB_NAME:定义了数据库的名称。

13)USR_ORA_INST_NAME@SERVERNAME(<节点名>):定义了数据库在该节点上的实例名。默认情况下数据库的实例名格式为<数据库名><节点编号>。

14)USR_ORA_STOP_MODE:定义了停止数据库的选项。如果该值为immediate,表示agent会通过shutdown immediate的方式停止数据库实例;如果该值为abort,表示agent会通过shutdown abort的方式停止数据库实例。

以下是数据库资源的属性列表输出,大家可以对应以上的说明查看。

[grid@test1 ~]$ crsctl stat res ora.ora11g.db -p NAME=ora.ora11g.db TYPE=ora.database.type ACL=owner:oracle:rwx,pgrp:oinstall:r--,other::r--,group:dba:r-x,user:grid:r-x ACTION_FAILURE_TEMPLATE= ACTION_SCRIPT= ACTIVE_PLACEMENT=1 AGENT_FILENAME=%CRS_HOME%/bin/oraagent%CRS_EXE_SUFFIX% AUTO_START=restore CARDINALITY=2 CHECK_INTERVAL=1 CHECK_TIMEOUT=30 CLUSTER_DATABASE=true DATABASE_TYPE=RAC DB_UNIQUE_NAME=ora11g DEFAULT_TEMPLATE=PROPERTY(RESOURCE_CLASS=database) PROPERTY(DB_UNIQUE_NAME= CONCAT(PARSE(%NAME%,.,2),%USR_ORA_DOMAIN%,.)) ELEMENT(INSTANCE_NAME= %GEN_USR_ORA_INST_NAME%) ELEMENT(DATABASE_TYPE= %DATABASE_TYPE%) DEGREE=1 DESCRIPTION=Oracle Database resource ENABLED=1 ENABLED@SERVERNAME(test1)=1 FAILOVER_DELAY=0 FAILURE_INTERVAL=60 FAILURE_THRESHOLD=1 GEN_AUDIT_FILE_DEST=/u01/app/oracle/admin/ora11g/adump GEN_START_OPTIONS= GEN_START_OPTIONS@SERVERNAME(test1)=open GEN_START_OPTIONS@SERVERNAME(test2)=open GEN_USR_ORA_INST_NAME= GEN_USR_ORA_INST_NAME@SERVERNAME(test1)=ora11g1 GEN_USR_ORA_INST_NAME@SERVERNAME(test2)=ora11g2 …… ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1 ORACLE_HOME_OLD= PLACEMENT=restricted PROFILE_CHANGE_TEMPLATE= RESTART_ATTEMPTS=2 ROLE=PRIMARY SCRIPT_TIMEOUT=60 SERVER_POOLS=ora.ora11g SPFILE=+DATA1/ora11g/spfileora11g.ora START_DEPENDENCIES=hard(ora.DATA1.dg) weak(type:ora.listener.type,global:type:ora.scan_listener.type,uniform:ora.ons,global:ora.gns) pullup(ora.DATA1.dg) START_TIMEOUT=600 STATE_CHANGE_TEMPLATE= STOP_DEPENDENCIES=hard(intermediate:ora.asm,shutdown:ora.DATA1.dg) STOP_TIMEOUT=600 TYPE_VERSION=3.2 UPTIME_THRESHOLD=1h USR_ORA_DB_NAME=ora11g …… USR_ORA_INST_NAME@SERVERNAME(test1)=ora11g1 USR_ORA_INST_NAME@SERVERNAME(test2)=ora11g2 USR_ORA_OPEN_MODE=open USR_ORA_OPI=false USR_ORA_STOP_MODE=immediate VERSION=11.2.0.4.0
复制

(10)数据库服务资源(ora.<数据库名>.<服务名>.svc)

在11gR2版本的集群中,数据库服务资源变成了一个资源(.svc资源),之前版本中的.cs和.srv资源已经不再存在。而CRSD管理资源的方式实际上和10gR2版本是相同的。用户可以根据需要为数据库创建多个服务资源来实现应用程序分区、负载均衡和高可用性。对于应用程序负载均衡和高可用性的内容,作者会在第13章中详细介绍。下面介绍数据库服务资源的属性AGENT_FILENAME。

AGENT_FILENAME:定义了管理该资源的agent进程(oraagent_oracle)。

(11)CVU资源(ora.cvu)

从版本11.2.0.2开始,GI会定期(默认情况下每6小时)运行cluvfy命令对集群的健康性进行检查(Cluvfy Comp Healthcheck),并记录相应的检查结果。CRSD是通过资源ora.cvu来实现的。

默认情况下,第一个加入集群的节点会运行ora.cvu资源,并定期对集群进行健康性检查。需要说明的是,该资源只会对集群进行健康检查,并将查询到的问题显示出来,但是不会对集群做任何修改。我们可以通过以下的一些资源属性来了解这个资源的更多信息。

[grid@test2 ~]$ crsctl stat res ora.cvu -p NAME=ora.cvu …… ACTION_SCRIPT=%CRS_HOME%/bin/cvures%CRS_SCRIPT_SUFFIX% …… AGENT_FILENAME=%CRS_HOME%/bin/scriptagent …… CARDINALITY=1 CHECK_INTERVAL=21600 CHECK_RESULTS=PRVF-5415 : Check to see if NTP daemon or service is running failed,PRVG-1101 : SCAN name "cluster-scan1" failed to resolve,PRVF-4657 : Name resolution setup check for "cluster-scan1" (IP address: 10.182.208.29) failed,PRVF-4664 : Found inconsistent name resolution entries for SCAN name "cluster-scan1",The Free Space Component check failed on node(s) "test1" …… DESCRIPTION=Oracle CVU resource …… START_DEPENDENCIES=hard(ora.net1.network) pullup(ora.net1.network) …… STOP_DEPENDENCIES=hard(ora.net1.network) ……
复制

其中:

AGENT_FILENAME指定了管理该资源的代理进程,我们能看到ora.cvu资源是由script-agent管理的。

ACTION_SCRIPT指定了管理该资源的具体脚本,我们能看到脚本名为/cvures。以下是该脚本的一小段,大家可以清晰地看到该脚本定义了资源的start、stop、check和abort操作。

case "$COMMAND" in 'start') <<<< start 操作 $ECHO "start cvu" …… 'clean') $ECHO "clean cvu" CLEANRC=$SUCC …… 'stop') <<<< stop 操作 $ECHO "stop cvu" …… 'check') <<<< check 操作 $ECHO "check cvu" if [ -f $RUNFILE ]; then …… 'abort') <<<< abort 操作 $ECHO "abort cvu" …… *) $ECHO "Usage: cvures {start|stop|check|clean|abort}" exit 1 esac
复制

其中:

CARDINALITY指定了集群中同时可以有多少个节点运行该资源,我们看到ora.cvu只会在一个节点上运行。

CHECK_INTERVAL指定了运行check操作的时间间隔为21600秒=360分钟=6小时。

CHECK_RESULTS会把每次cluvfy健康检查找到的问题显示出来。

START_DEPENDENCIES和STOP_DEPENDENCIES说明CVU资源是需要依赖于集群公网资源的。

(12)使用srvctl命令

之前作者一直在使用命令crsctl stat res<资源名>-p来查看资源的很多属性,这样更容易说明每个资源的特点,但是很多读者觉得这比较难懂,所以作者介绍下面一些简单的srvctl命令来查看CRSD所管理资源的基本配置,srvctl命令提供的输出的可读性会好很多。

network资源:

[grid@test1 ~]$ srvctl config network -k 1 Network exists: 1/10.182.208.0/255.255.255.0/eth0,type static
复制

其中,1代表网络资源的编号。

VIP资源:

[grid@test1 ~]$ srvctl config vip -n test1 VIP exists: /test1-vip/10.182.208.34/10.182.208.0/255.255.255.0/eth0,hosting node test1
复制

SCAN VIP资源:

[grid@test1 ~]$ srvctl config scan SCAN name: cluster-scan1,Network: 1/10.182.208.0/255.255.255.0/eth0 SCAN VIP name: scan1,IP: /cluster-scan1/10.182.208.29
复制

Listener资源:

[grid@test1 ~]$ srvctl config listener -l LISTENER Name: LISTENER Network: 1,Owner: grid Home: <CRS home> End points: TCP:1521
复制

SCAN Listener资源:

[grid@test1 ~]$ srvctl config scan_listener SCAN Listener LISTENER_SCAN1 exists. Port: TCP:1521
复制

ASM资源:

[grid@test1 ~]$ srvctl config asm -a ASM home: /u01/app/11.2.0.4/grid ASM listener: LISTENER ASM is enabled.
复制

磁盘组资源:

[grid@test1 ~]$ srvctl status diskgroup -g DATA1 Disk Group DATA1 is running on test1
复制

数据库资源:

[grid@test1 ~]$ srvctl config database -d ora11g -a Database unique name: ora11g Database name: ora11g Oracle home: /u01/app/oracle/product/11.2.0.4/db_1 Oracle user: oracle Spfile: +DATA1/ora11g/spfileora11g.ora Domain: Start options: open Stop options: immediate Database role: PRIMARY Management policy: AUTOMATIC Server pools: ora11g Database instances: ora11g1,ora11g2 Disk Groups: DATA1 Mount point paths: Services: test Type: RAC Database is enabled Database is administrator managed
复制

数据库服务资源:

[grid@test1 ~]$ srvctl config service -d ora11g -s test -v Service name: test Service is enabled Server pool: ora11g_test Cardinality: 1 Disconnect: false Service role: PRIMARY Management policy: AUTOMATIC DTP transaction: false AQ HA notifications: false Failover type: NONE Failover method: NONE TAF failover retries: 0 TAF failover delay: 0 Connection Load Balancing Goal: LONG Runtime Load Balancing Goal: NONE TAF policy specification: NONE Edition: Preferred instances: ora11g1 Available instances: ora11g2
复制

(13)小结

从以上对CRSD管理的资源的介绍中,大家可以看到:绝大部分的资源都是由root或者grid用户对应的代理进程来管理的,只有数据库资源和数据库服务资源是由Oracle用户对应的代理进程来管理的。事实上这也反映出了11.2版本集群的一个方向:数据库越来越像是GI管理的一个资源,在集群中的地位也变得不那么重要了;ASM会变成集群的基础组件,提供存储服务、卷管理器和文件系统服务;集群管理的资源越来越多。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

星星之火
暂无图片
1年前
评论
暂无图片 0
真正的智慧是接纳,外不起纷争,内不生对立;不与天斗,不与人争,不和自己闹别扭。真正的智慧是接纳,外不起纷争,内不生对立;不与天斗,不与人争,不和自己闹别扭。真正的智慧是接纳,外不起纷争,内不生对立;不与天斗,不与人争,不和自己闹别扭。
1年前
暂无图片 点赞
评论
不想用随机名字
暂无图片
3年前
评论
暂无图片 0
Mark,辛苦,期待更新
3年前
暂无图片 点赞
评论