Oracle Policy-Managed Cluster – Growing for DBaaS

Policy-Managed Cluster在Oracle 11gR2中被引进,在Oracle 12c中使用dbca创建RAC数据库的时候,Policy-Managed选项已然成为默认值。 Policy-Managed RAC

那么到底什么是Policy-Managed方式的集群和数据库呢?与以前的Admin-Managed方式有何区别?何种环境适合使用这种新的方式进行管理?本文尝试回答这些问题,并且做出简单的测试。

什么是Policy-Managed方式?

基于策略的管理方式,是以服务器池(Server Pools)为基础的,简单地说,就是先定义一些服务器池,池中包含一定量的服务器,然后再定义一些策略,根据这些策略Oracle会自动决定让多少数据库实例运行在池中的几台机器上。数据库实例名后缀、数据库实例个数、所运行的主机,这些都是通过策略决定的,而不是数据库管理员事先定好的。

与Admin-Managed方式有何区别?

实际上上面的表述已经明确说明了,Policy-Managed和Admin-Managed方式的差别。让我们再回顾一下,在以往我们创建一个RAC数据库大概是怎样的方法,我们在dbca的界面中会选择要将数据库实例运行在整个集群中的几台机器上,或者是2台或者是3台,甚或是更多,但是只要在安装的时候选定几台机器,那么以后如果不做增减节点的操作,就始终会在这几台机器上运行。而且,通常会根据主机名称的排序自动将每台主机上的数据库实例依次命名为dbname1到dbnameN。这些在管理员安装完毕以后,都不会再自动变化,这就是Admin-Managed方式。

何种环境适合使用这种新的方式进行管理?

当管理大量的服务器集群,并且在这些集群中运行着多种不同重要程度,不同策略的RAC数据库时,为了简化管理,建议使用Policy-Managed方式,实际上Oracle也建议只有在超过3台的服务器的时候才使用Policy-Managed来管理整个数据库集群。想象一下使用Policy-Managed方式可以达到的效果:如果我们有10台服务器组成,根据不同的应用的重要性定义服务器池的关键程度,然后在其中某些机器意外停机的情况下,仍然可以自动地保持足够多的机器给重要的系统提供数据库服务,而将不关键的系统数据库服务器个数降低到最低限度。

那么Policy-Managed方式到底长什么样?

在默认安装完Oracle 12c的RAC数据库之后,发现数据库实例始终只会启动在一个节点中。检查服务器池配置。

[oracle@dbserver2 ~]$ srvctl config srvpool
Server pool name: Free
Importance: 0, Min: 0, Max: -1
Category:
Candidate server names:
Server pool name: Generic
Importance: 0, Min: 0, Max: -1
Category:
Candidate server names:
Server pool name: orcl_pool
Importance: 0, Min: 0, Max: 1
Category: hub
Candidate server names:

Free池和Generic池是默认存在的,orcl_pool池则是在dbca创建数据库的时候由我们自己定义的。其中Min: 0, Max: 1表示在这个池中最少允许有0台机器,最多允许有1台机器被使用。所以这也造成了使用这个服务器池的数据库实例始终只会启动在一个节点中,即使这在我们最初的定义中是一个RAC数据库。

当前的数据库实例启动在节点2中,比较一下节点1和节点2服务器使用情况的输出。

[grid@dbserver2 ~]$ crsctl status server dbserver1 -f
NAME=dbserver1
MEMORY_SIZE=3954
CPU_COUNT=1
CPU_CLOCK_RATE=2
CPU_HYPERTHREADING=0
CPU_EQUIVALENCY=1000
DEPLOYMENT=other
CONFIGURED_CSS_ROLE=hub
RESOURCE_USE_ENABLED=1
SERVER_LABEL=
PHYSICAL_HOSTNAME=
STATE=ONLINE
ACTIVE_POOLS=Free --此处显示未Free,表示节点1中不属于任何正在运行的服务器池资源。
STATE_DETAILS=
ACTIVE_CSS_ROLE=hub

[grid@dbserver2 ~]$ crsctl status server dbserver2 -f
NAME=dbserver2
MEMORY_SIZE=3954
CPU_COUNT=1
CPU_CLOCK_RATE=2
CPU_HYPERTHREADING=0
CPU_EQUIVALENCY=1000
DEPLOYMENT=other
CONFIGURED_CSS_ROLE=hub
RESOURCE_USE_ENABLED=1
SERVER_LABEL=
PHYSICAL_HOSTNAME=
STATE=ONLINE
ACTIVE_POOLS=ora.orcl_pool --此处显示节点2正运行在orcl_pool服务器池资源中。
STATE_DETAILS=
ACTIVE_CSS_ROLE=hub

接下来需要修改一下配置,让RAC数据库以我们熟知的方式启动在多个节点上。 –修改orcl_pool池中最少运行一台机器,最多运行2台机器,还记得我们前面说的关键程度吗?importance表示该池的关键程度,数字越大表示关键程度越高,越优先被考虑满足Min条件。

[oracle@dbserver2 ~]$ srvctl modify srvpool -serverpool orcl_pool -importance 5 -min 1 -max 2

–重新检查服务器池信息,可以看到已经修改成功,Min: 1, Max: 2

[oracle@dbserver2 ~]$ srvctl config srvpool
Server pool name: Free
Importance: 0, Min: 0, Max: -1
Category:
Candidate server names:
Server pool name: Generic
Importance: 0, Min: 0, Max: -1
Category:
Candidate server names:
Server pool name: orcl_pool
Importance: 5, Min: 1, Max: 2
Category: hub
Candidate server names:

–查看当前服务器池的状态,可以看到orcl_pool池中激活的服务器包括了节点1和节点2两台机器。

[grid@dbserver1 ~]$ crsctl status serverpool
NAME=Free
ACTIVE_SERVERS=

NAME=Generic
ACTIVE_SERVERS=

NAME=ora.orcl_pool
ACTIVE_SERVERS=dbserver1 dbserver2

在修改完毕以后,节点1中的数据库实例就会自动启动,我们可以通过crsctl命令查看服务器的状态,其中STATE_DETAILS字段显示了正在启动资源,在正常启动完毕以后该字段会显示为空。

[grid@dbserver2 ~]$ crsctl status server dbserver1 -f
NAME=dbserver1
MEMORY_SIZE=3954
CPU_COUNT=1
CPU_CLOCK_RATE=2
CPU_HYPERTHREADING=0
CPU_EQUIVALENCY=1000
DEPLOYMENT=other
CONFIGURED_CSS_ROLE=hub
RESOURCE_USE_ENABLED=1
SERVER_LABEL=
PHYSICAL_HOSTNAME=
STATE=ONLINE
ACTIVE_POOLS=ora.orcl_pool
STATE_DETAILS=STARTING RESOURCES
ACTIVE_CSS_ROLE=hub

现在就出现了一个比较尴尬的情况(对于我们以前管理RAC的常识来说),由于dbserver1中的实例是后启动的,因此实例名后缀为2,而dbserver2中的实例名后缀是1,实际上,在Policy-Managed管理的RAC环境中,无需关注到底哪个实例启动在哪台机器上,我们需要的就是通过SCAN IP,通过Service名去访问数据库就好,而不需要通过实例名访问数据库。但是这里为了测试一下功能,还是决定1归1,2归2,我有说过我是完美主义者吗?

--先将dbserver1上的数据库服务资源reolocate到dbserver2中,这样实例2就运行回到了dbserver2中。
[grid@dbserver1 ~]$ crsctl relocate resource ora.orcl12c.db -s dbserver1 -n dbserver2
--再将dbserver1中的实例启动,因为实例2已经启动在dbserver2中,因此即使此时该实例是后启动的,但是仍然还是会命名为实例1。
[oracle@dbserver1 ~]$ srvctl start instance -db orcl12c -node dbserver1

最后将这个RAC数据库再改回到只会启动一个实例的默认状态。

[oracle@dbserver2 ~] srvctl modify srvpool -serverpool orcl_pool -min 0 -max 1

以后,无论是启动在哪台机器上,数据库的实例名永远会是dbname_1(注意,这里有一个下划线,这是Policy-Managed数据库实例的命名规则)。而我们访问数据库,则不应该指定实例名。比如:

sqlplus sys/passwd@db-cluster-scan:1521/orcl12c as sysdba

因为现在你已经无需关心到底实例是启动在哪台机器上了,后面是一个资源池,是不是有些熟悉这样的表述,是的,没错,Cloud! 我们也贴上了Cloud这个红到发紫的词,这就是Oracle私有云解决方案的构成组件之一。

Install 11.2.0.2 RAC on OEL5.5 x86-64 (root.sh issue on second node)

在安装11.2.0.2 RAC的时候,第一步安装Grid,在第二个节点上运行root.sh的时候,报错如下:

Start of resource "ora.ctssd" failed
CRS-2672: Attempting to start 'ora.ctssd' on 'xsh-server2'
CRS-2674: Start of 'ora.ctssd' on 'xsh-server2' failed
CRS-4000: Command Start failed, or completed with errors.
Cluster Time Synchronisation Service  start in exclusive mode failed at /u01/app/11.2.0/grid/crs/install/crsconfig_lib.pm line 6455.
/u01/app/11.2.0/grid/perl/bin/perl -I/u01/app/11.2.0/grid/perl/lib -I/u01/app/11.2.0/grid/crs/install /u01/app/11.2.0/grid/crs/install/rootcrs.pl execution failed

从报错信息上看是ctssd进程启动失败(在这之前会显示cssd进程启动成功,这与MOS上的其它一些第二节点运行root.sh失败的情形是不一样的,那些场景在cssd进程启动的时候就失败了),查看ctssd进程的启动log(位于$GRID_HOME/log/ctssd目录下),发现如下错误信息。

2010-11-12 18:55:46.132: [    GIPC][2424495392] gipcCheckInitialization: possible incompatible non-threaded init from [prom.c : 687], original from [clsss.c : 5325]
[ default][2424495392]Failure 4 in trying to open SV key SYSTEM.version.localhost

[ default][2424495392]procr_open_key error 4 errorbuf : PROCL-4: The local registry key to be operated on does not exist.

2010-11-12 18:55:46.135: [    CTSS][2424495392]clsctss_r_av2: Error [3] retrieving Active Version from OLR. Returns [19].
2010-11-12 18:55:46.138: [    CTSS][2424495392](:ctss_init16:): Error [19] retrieving active version. Returns [19].
2010-11-12 18:55:46.138: [    CTSS][2424495392]ctss_main: CTSS init failed [19]
2010-11-12 18:55:46.138: [    CTSS][2424495392]ctss_main: CTSS daemon aborting [19].
2010-11-12 18:55:46.138: [    CTSS][2424495392]CTSS daemon aborting

从crsctl命令中也可以看出ora.cssd启动成功,但是ora.ctssd是OFFLINE状态。

 $ crsctl stat res -t -init
--------------------------------------------------------------------------------
NAME           TARGET  STATE        SERVER                   STATE_DETAILS       
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.asm
      1        OFFLINE OFFLINE                                                   
ora.cluster_interconnect.haip
      1        OFFLINE OFFLINE                                                   
ora.crf
      1        OFFLINE OFFLINE                                                   
ora.crsd
      1        OFFLINE OFFLINE                                                   
ora.cssd
      1        ONLINE  ONLINE       xsh-server2                                  
ora.cssdmonitor
      1        ONLINE  ONLINE       xsh-server2                                  
ora.ctssd
      1        ONLINE  OFFLINE                                                   
ora.diskmon
      1        ONLINE  ONLINE       xsh-server2                                  
ora.drivers.acfs
      1        OFFLINE OFFLINE                                                   
ora.evmd
      1        OFFLINE OFFLINE                                                   
ora.gipcd
      1        ONLINE  ONLINE       xsh-server2                                  
ora.gpnpd
      1        ONLINE  ONLINE       xsh-server2                                  
ora.mdnsd
      1        ONLINE  ONLINE       xsh-server2   

此时如果用此命令查看第一个节点的状况会发现所有资源都是正常ONLINE的。继续检查cssd.log(位于$GRID_HOME/log/cssd目录中),显示在发现ASM磁盘的时候报错。

2010-11-12 13:44:30.505: [   SKGFD][1087203648]UFS discovery with :ORCL:VOL*:

2010-11-12 13:44:30.505: [   SKGFD][1087203648]OSS discovery with :ORCL:VOL*:

2010-11-12 13:44:30.505: [   SKGFD][1087203648]Discovery with asmlib :ASM:/opt/oracle/extapi/64/asm/orcl/1/libasm.so: str :ORCL:VOL*:

2010-11-12 13:44:30.505: [   SKGFD][1087203648]Fetching asmlib disk :ORCL:VOL1:

2010-11-12 13:44:30.505: [   SKGFD][1087203648]Fetching asmlib disk :ORCL:VOL2:

2010-11-12 13:44:30.505: [   SKGFD][1087203648]Fetching asmlib disk :ORCL:VOL3:

2010-11-12 13:44:30.505: [   SKGFD][1087203648]ERROR: -15(asmlib ASM:/opt/oracle/extapi/64/asm/orcl/1/libasm.so op asm_open error Operation not permitted
)
2010-11-12 13:44:30.505: [   SKGFD][1087203648]ERROR: -15(asmlib ASM:/opt/oracle/extapi/64/asm/orcl/1/libasm.so op asm_open error Operation not permitted
)
2010-11-12 13:44:30.505: [   SKGFD][1087203648]ERROR: -15(asmlib ASM:/opt/oracle/extapi/64/asm/orcl/1/libasm.so op asm_open error Operation not permitted

值得注意的是,这样的报错在第一个节点上也同样存在,但是第一个节点上所有的资源包括ASM磁盘组却都是正常运行的。

对于以上cssd.log中的错误,按照MOS Note [1050164.1]处理,修改/etc/sysconfig/oracleasm-_dev_oracleasm文件,指定ASMLib在发现磁盘的时候需要忽略的盘和需要检查的盘。在我们的环境中是使用了Multipath来对多块磁盘做多路径处理,因此需要包括dm开头的磁盘,而忽略sd开头的磁盘。这样的问题也应该只会发生在使用了Multipath的磁盘上。

# ORACLEASM_SCANORDER: Matching patterns to order disk scanning
ORACLEASM_SCANORDER="dm"

# ORACLEASM_SCANEXCLUDE: Matching patterns to exclude disks from scan
ORACLEASM_SCANEXCLUDE="sd"

可以通过以下方法来确认是否遭遇了此问题。

# ls -l /dev/oracleasm/disks
brw-rw---- 1 oracle dba 3, 65 May 14 12:08 CRSVOL
# cat /proc/partitions
  3 65 4974448 sda
253  1 4974448 dm-1

在上面可以看到CRSVOL这个用oracleasm创建的ASM磁盘的major和minor号分别是3,65,而这正是/dev/sda的号,并不是/dev/dm-1的号,所以表示在创建ASM磁盘组的时候并没有使用到Multipath设备。通常情况下,在节点1上是正确的,而在节点2上不正确的,因此出现了问题。

在处理完以上问题以后,必须要对grid环境做deconfig再reconfig,而不能只是在失败节点上重新运行root.sh(我在这里耗费了大量时间),重新配置grid的步骤可以参考MOS Note [942166.1] – How to Proceed from Failed 11gR2 Grid Infrastructure (CRS) Installation。之后root.sh顺利在第二节点上运行成功。

在错误解决以后,回顾之前的安装信息,可以发现虽然第一个节点显示所有资源都正常,但是和正常的root.sh运行信息相比则缺少了几行显示。

正常的信息如下:

# $GRID_HOME/root.sh
Running Oracle 11g root script...

The following environment variables are set as:
    ORACLE_OWNER= grid
    ORACLE_HOME=  /u01/app/11.2.0/grid

Enter the full pathname of the local bin directory: [/usr/local/bin]: 
The contents of "dbhome" have not changed. No need to overwrite.
The contents of "oraenv" have not changed. No need to overwrite.
The contents of "coraenv" have not changed. No need to overwrite.

Entries will be added to the /etc/oratab file as needed by
Database Configuration Assistant when a database is created
Finished running generic part of root script.
Now product-specific root actions will be performed.
Using configuration parameter file: /u01/app/11.2.0/grid/crs/install/crsconfig_params
LOCAL ADD MODE 
Creating OCR keys for user 'root', privgrp 'root'..
Operation successful.
OLR initialization - successful
Adding daemon to inittab
ACFS-9200: Supported
ACFS-9300: ADVM/ACFS distribution files found.
ACFS-9307: Installing requested ADVM/ACFS software.
ACFS-9308: Loading installed ADVM/ACFS drivers.
ACFS-9321: Creating udev for ADVM/ACFS.
ACFS-9323: Creating module dependencies - this may take some time.
ACFS-9327: Verifying ADVM/ACFS devices.
ACFS-9309: ADVM/ACFS installation correctness verified.
CRS-2672: Attempting to start 'ora.mdnsd' on 'xsh-server1'
CRS-2676: Start of 'ora.mdnsd' on 'xsh-server1' succeeded
CRS-2672: Attempting to start 'ora.gpnpd' on 'xsh-server1'
CRS-2676: Start of 'ora.gpnpd' on 'xsh-server1' succeeded
CRS-2672: Attempting to start 'ora.cssdmonitor' on 'xsh-server1'
CRS-2672: Attempting to start 'ora.gipcd' on 'xsh-server1'
CRS-2676: Start of 'ora.cssdmonitor' on 'xsh-server1' succeeded
CRS-2676: Start of 'ora.gipcd' on 'xsh-server1' succeeded
CRS-2672: Attempting to start 'ora.cssd' on 'xsh-server1'
CRS-2672: Attempting to start 'ora.diskmon' on 'xsh-server1'
CRS-2676: Start of 'ora.diskmon' on 'xsh-server1' succeeded
CRS-2676: Start of 'ora.cssd' on 'xsh-server1' succeeded

ASM created and started successfully.

Disk Group CRSDG created successfully.

clscfg: -install mode specified
Successfully accumulated necessary OCR keys.
Creating OCR keys for user 'root', privgrp 'root'..
Operation successful.
Successful addition of voting disk 67463e71af084f76bf98b3ee55081e40.
Successfully replaced voting disk group with +CRSDG.
CRS-4266: Voting file(s) successfully replaced
##  STATE    File Universal Id                File Name Disk group
--  -----    -----------------                --------- ---------
 1. ONLINE   67463e71af084f76bf98b3ee55081e40 (ORCL:VOL1) [CRSDG]
Located 1 voting disk(s).

CRS-2672: Attempting to start 'ora.asm' on 'xsh-server1'
CRS-2676: Start of 'ora.asm' on 'xsh-server1' succeeded
CRS-2672: Attempting to start 'ora.CRSDG.dg' on 'xsh-server1'
CRS-2676: Start of 'ora.CRSDG.dg' on 'xsh-server1' succeeded
ACFS-9200: Supported
ACFS-9200: Supported
CRS-2672: Attempting to start 'ora.registry.acfs' on 'xsh-server1'
CRS-2676: Start of 'ora.registry.acfs' on 'xsh-server1' succeeded
Preparing packages for installation...
cvuqdisk-1.0.9-1
Configure Oracle Grid Infrastructure for a Cluster ... succeeded

而之前的信息则缺少了以下4行。

LOCAL ADD MODE 
Creating OCR keys for user 'root', privgrp 'root'..
Operation successful.
OLR initialization - successful

Oracle显然不会承认这是bug,好吧,解决问题就好。

Tips for Installing Oracle11gR2 RAC on AIX 6.1

不准备写一篇完整的Installation Guide,安装光盘中自带的pdf文档已经足够。本文只是总结一些在安装过程中碰到的问题或者说应该要注意的要点。

1. 如下命令的软件包需要配全,通常在安装完操作系统以后就应该已经都有了。

lslpp -l bos.adt.base bos.adt.lib bos.adt.libm bos.perf.libperfstat \
 bos.perf.perfstat bos.perf.proctools rsct.basic.rte rsct.compat.clients.rte xlC.aix61.rte

2. 安装文档中提到的fix即使不存在也不影响安装。

# instfix -i -k "IZ41855 IZ51456 IZ52319"
    There was no data for IZ41855 in the fix database.
    All filesets for IZ51456 were found.
    There was no data for IZ52319 in the fix database.

3. 11gR2 RAC自带CTSS时间同步服务,因此安装文档中要求禁用NTP,但是在安装过程中最后检查的时候,仍然会报NTP服务无法使用,可以直接忽略。

4. 11gR2 RAC安装中对于用户和用户组的建议可以说比以前复杂很多,不再仅仅是oinstall和dba这两个用户组。为了方便我们仍然可以只创建oinstall和dba这两个用户组,但是建议按照安装文档中描述的那样创建grid和oracle这两个用户,用grid用户安装Grid Infrastructure,用oracle用户安装RAC。

5. 11gR2中OCR和Voting是可以放置在ASM磁盘组中,因此实际上在整个数据库环境中,应该会存在至少三个ASM Disk Group,也就是crsdg(用于GRID使用)、datadg(数据库数据文件)、fradg(闪回区)。这里需要特别注意,所有磁盘组都是用grid用户执行asmca来创建的(当然你可以用create diskgroup命令创建),而最后数据库实例是以oracle用户启动的,也就是oracle用户也必须有读写磁盘组中disk的权限。

假设我们的环境中有rhdisk2、rhdisk3、rhdisk4三个LUN分别对应crsdg、datadg和fradg,那么建议做如下的权限设置:

chown grid:oinstall /dev/rhdisk2
chown grid:oinstall /dev/rhdisk3
chown grid:oinstall /dev/rhdisk4
chmod 660 /dev/rhdisk3
chmod 660 /dev/rhdisk4

# ls -l /dev/rhdisk*
crw-------    1 grid     oinstall     23,  3 Jun 01 16:23 /dev/rhdisk2
crw-rw----    1 grid     oinstall     23,  4 Jun 01 16:13 /dev/rhdisk3
crw-rw----    1 grid     oinstall     23,  2 Jun 01 16:13 /dev/rhdisk4

6. 新增的SCAN VIP其实可有可无,特别对于不会频繁增删数据库节点的环境,个人觉得几乎无用。而且实际上,SCAN VIP和SCAN VIP LISTENER的切换操作十分缓慢,在我的测试中relocate scan的操作大概需要花费2分钟才能完成,不确认是不是我个人的配置问题。

SCAN VIP也同样是绑定在RAC环境中的某个节点上。如下SCAN VIP则是绑定在dbserver2中的public网卡上,可以看到public网卡上总共有3个IP,一个是实IP,一个是VIP,一个是SCAN VIP。

# crs_stat -t|grep scan
ora....N1.lsnr ora....er.type ONLINE    ONLINE    dbserver2 
ora.scan1.vip  ora....ip.type ONLINE    ONLINE    dbserver2 

# srvctl config scan_listener
SCAN Listener LISTENER_SCAN1 exists. Port: TCP:1521

# srvctl config scan
SCAN name: crs-scan.cnrmall.com, Network: 1/192.168.255.0/255.255.255.0/en0
SCAN VIP name: scan1, IP: /crs-scan.cnrmall.com/192.168.255.250

# netstat -in
Name  Mtu   Network     Address           ZoneID    Ipkts Ierrs    Opkts Oerrs  Coll
en0   1500  link#2      0.21.5e.48.e4.60       -    96331     0    47140     0     0
en0   1500  192.168.255 192.168.255.225        -    96331     0    47140     0     0
en0   1500  192.168.255 192.168.255.235        -    96331     0    47140     0     0
en0   1500  192.168.255 192.168.255.250        -    96331     0    47140     0     0
en1   1500  link#3      0.21.5e.48.e4.61       -   342409     0   293503     0     0
en1   1500  172.16      172.16.0.2             -   342409     0   293503     0     0
lo0   16896 link#1                             -   103667     0   103678     0     0
lo0   16896 127         127.0.0.1              -   103667     0   103678     0     0
lo0   16896 ::1                                0   103667     0   103678     0     0

7. SCAN VIP在Oracle安装文档的建议中是需要配置在DNS服务器中,实际上也可以使用/etc/hosts文件,并且除却SCAN VIP之外的public ip、vip、private ip也仍然都是可以跟以前一样,配置在/etc/hosts文件中。

8. 安装11gR2 RAC要求必须配置ssh用户对等性,以前配置rsh的方式现在已经无法通过安装检查。OUI中提供了自动配置ssh用户对等性的按钮,因此无需再事先手动配置。

需要注意的是:该功能完全针对Linux环境进行的开发,因此在AIX环境中,需要事先作如下操作:

ln -s /usr/bin/ksh /bin/bash
mkdir -p /usr/local/bin
ln -s /usr/bin/ssh-keygen /usr/local/bin/ssh-keygen

在配置对等性时,OUI会使用/bin/bash,而AIX默认是没有bash的,因此需要将ksh软链接到bash(当然你也可以安装bash包)。
同样,OUI会使用/usr/local/bin/ssh-keygen产生对等性密钥,而AIX中在安装了OpenSSH以后,ssh-keygen命令默认是存储在/usr/bin中,因此也需要做link。

9. 在成功安装完Grid Infrastructure之后,运行cluvf命令可能会报错。

# cluvfy comp nodeapp -verbose

ERROR: 
CRS is not installed on any of the nodes
Verification cannot proceed

并且,在碰到这样的错误之后,也无法安装RAC,会碰到如下错误:

[INS-35354] The system on which you are attempting to install Oracle RAC is not part of a valid cluster.

也就是无论是cluvf命令还是OUI,都认为这个机器上没有安装CRS,并不是在一个集群环境中。但是实际上运行crsctl check crs命令是完全正常的。

这个错误的解决方法可以参看Metalink Note [ID 798203.1],大体上来说就是在安装Grid Infrastructure的时候,inventory.xml文件中丢掉了CRS=”true”字样,这无疑是安装程序的bug。需要手工detachHome再attachHome。

10. 11gR2 RAC在CRS资源部分做了很多改动,创建完RAC数据库以后的默认资源比以前多了不少。

# crs_stat -t
Name           Type           Target    State     Host        
------------------------------------------------------------
ora.CRSDG.dg   ora....up.type ONLINE    ONLINE    dbserver1   
ora.DATADG.dg  ora....up.type ONLINE    ONLINE    dbserver1   
ora.FRADG.dg   ora....up.type ONLINE    ONLINE    dbserver1   
ora....ER.lsnr ora....er.type ONLINE    ONLINE    dbserver1   
ora....N1.lsnr ora....er.type ONLINE    ONLINE    dbserver2   
ora.asm        ora.asm.type   ONLINE    ONLINE    dbserver1   
ora.dbcnr.db   ora....se.type ONLINE    ONLINE    dbserver2   
ora....SM1.asm application    ONLINE    ONLINE    dbserver1   
ora....R1.lsnr application    ONLINE    ONLINE    dbserver1   
ora....er1.gsd application    OFFLINE   OFFLINE               
ora....er1.ons application    ONLINE    ONLINE    dbserver1   
ora....er1.vip ora....t1.type ONLINE    ONLINE    dbserver1   
ora....SM2.asm application    ONLINE    ONLINE    dbserver2   
ora....R2.lsnr application    ONLINE    ONLINE    dbserver2   
ora....er2.gsd application    OFFLINE   OFFLINE               
ora....er2.ons application    ONLINE    ONLINE    dbserver2   
ora....er2.vip ora....t1.type ONLINE    ONLINE    dbserver2   
ora.eons       ora.eons.type  ONLINE    ONLINE    dbserver1   
ora.gsd        ora.gsd.type   OFFLINE   OFFLINE               
ora....network ora....rk.type ONLINE    ONLINE    dbserver1   
ora.oc4j       ora.oc4j.type  ONLINE    ONLINE    dbserver2   
ora.ons        ora.ons.type   ONLINE    ONLINE    dbserver1   
ora.scan1.vip  ora....ip.type ONLINE    ONLINE    dbserver2 

启动数据库实例以后,可以看到11gR2的后台进程已经增加到了43个,说实话,我很怀念简单的Oracle8i。

# ps -ef|grep ora_ | grep -v grep
  oracle  364656       1   0 17:01:17      -  0:00 ora_mark_dbcnr1 
  oracle  540722       1   0 17:01:17      -  0:03 ora_mmnl_dbcnr1 
  oracle  561184       1   0 18:07:34      -  0:00 ora_q003_dbcnr1 
  oracle  643244       1   0 17:01:17      -  0:01 ora_mmon_dbcnr1 
  oracle  651360       1   0 17:01:16      -  0:00 ora_asmb_dbcnr1 
  oracle  655494       1   0 17:01:16      -  0:00 ora_rbal_dbcnr1 
  oracle  663680       1   1 17:01:13      -  0:06 ora_lmd0_dbcnr1 
  oracle  667794       1   0 17:01:12      -  0:00 ora_pmon_dbcnr1 
  oracle  671832       1   0 17:01:12      -  0:01 ora_diag_dbcnr1 
  oracle  675932       1   0 17:01:16      -  0:00 ora_smon_dbcnr1 
  oracle  679962       1   0 17:01:12      -  0:00 ora_gen0_dbcnr1 
  oracle  696414       1   0 17:01:16      -  0:00 ora_dbw0_dbcnr1 
  oracle  708790       1   0 17:02:33      -  0:00 ora_qmnc_dbcnr1 
  oracle  716930       1   0 17:01:17      -  0:04 ora_lck0_dbcnr1 
  oracle  721124       1   0 17:01:16      -  0:00 ora_mman_dbcnr1 
  oracle  725186       1   0 17:02:32      -  0:00 ora_gtx0_dbcnr1 
  oracle  729102       1   0 17:01:15      -  0:00 ora_lmhb_dbcnr1 
  oracle  737358       1   0 17:01:16      -  0:00 ora_reco_dbcnr1 
  oracle  745554       1   0 17:02:34      -  0:00 ora_q001_dbcnr1 
  oracle  749762       1   0 17:01:16      -  0:00 ora_lgwr_dbcnr1 
  oracle  753716       1   0 17:01:12      -  0:00 ora_ping_dbcnr1 
  oracle  766014       1   0 17:01:13      -  0:00 ora_psp0_dbcnr1 
  oracle  790688       1   0 17:01:13      -  0:00 ora_acms_dbcnr1 
  oracle  794780       1   0 17:01:12      -  0:02 ora_vktm_dbcnr1 
  oracle  815252       1   0 17:01:12      -  0:00 ora_dbrm_dbcnr1 
  oracle  819350       1   1 17:01:15      -  0:16 ora_lms1_dbcnr1 
  oracle  827642       1   0 17:02:36      -  0:01 ora_cjq0_dbcnr1 
  oracle  848054       1   0 17:02:30      -  0:00 ora_arc0_dbcnr1 
  oracle  856270       1   0 17:01:15      -  0:00 ora_rms0_dbcnr1 
  oracle  868590       1   0 17:25:42      -  0:00 ora_q002_dbcnr1 
  oracle  872622       1   0 17:01:15      -  0:16 ora_lms0_dbcnr1 
  oracle  901314       1   0 17:02:32      -  0:00 ora_arc3_dbcnr1 
  oracle  921600       1   0 18:07:17      -  0:00 ora_pz98_dbcnr1 
  oracle  925926       1   0 17:01:18      -  0:00 ora_rsmn_dbcnr1 
  oracle  929980       1   0 17:07:35      -  0:00 ora_smco_dbcnr1 
  oracle  942286       1   0 18:07:17      -  0:00 ora_pz99_dbcnr1 
  oracle  950274       1   0 17:02:32      -  0:00 ora_rcbg_dbcnr1 
  oracle  958498       1   0 17:02:31      -  0:00 ora_arc2_dbcnr1 
  oracle  974876       1   0 18:07:38      -  0:00 ora_w000_dbcnr1 
  oracle 1011914       1   0 17:01:16      -  0:01 ora_ckpt_dbcnr1 
  oracle 1052884       1   1 17:01:13      -  0:06 ora_lmon_dbcnr1 
  oracle 1069246       1   1 17:01:13      -  0:33 ora_dia0_dbcnr1 
  oracle 1110056       1   0 17:02:31      -  0:00 ora_arc1_dbcnr1 
# ps -ef|grep ora_ | grep -v grep | wc -l
      43
#

RAC Object Remastering (Dynamic Remastering)

原文作者:Riyaj Shamsudeen
原文链接:http://orainternals.wordpress.com/2010/03/25/rac-object-remastering-dynamic-remastering/

译者注:如果您对本文章有兴趣,请一定先去阅读Riyaj的原文,在万不得已时可以使用这篇译文校对一下自己的理解。译文中的master, mastering, remastering, affinity lock都翻译的不满意,甚至有些词左思右想还是保留了原文。IT技术从业者应该以英文为母语。

感谢Yong Huang,从跟他的邮件往来中得到了很多帮助。

***********以下为译文全文***********。
RAC Object Remastering (Dynamic Remastering)
by Riyaj Shamsudeen

在RAC环境中,每个数据块都被一个实例所掌控(mastered)。掌控一个数据块意思是主实例(master instance)始终监控这个数据块的状态,直到下一次重配置事件发生(因为实例重启或者其它原因)。

Hash to the master
这些数据库是根据数据块范围来掌控的。举例来说,数据块范围从file 10,block 1开始到block 128可能是被实例1所掌控,而从file 10,block 129到block 256是被实例2所掌控。当然,在不同的版本10g,11g中都有所不同,只是中心思想都是将数据块均衡地分布在不同实例上由此Global Cache grants可以在各实例间平衡分布。有趣的是,从10g以后版本数据块范围的长度是128(Julian Dyke提到在9i中是1089,但是我个人还没有测试过)。技术支持推荐取消db_file_multiblock_read_count初始化参数的设置这样将会自动调整到128,我猜这意味着通过较少的GC消息就可以进行完整的多块读。走题了。

更深入的,Michael Möller指出这种哈希算法有进一步优化:当通过数据块地址(DBA)初次计算主节点时使用到哈希算法,生成一个“虚拟属主”,然后在通过一个查询表(长度是最大允许的节点数,128?)再转化为真实(在线且打开的)属主。这意味着当有一个节点关闭或者启动的时候,RAC不需要为所有数据块再次计算哈希值,而只需要分发新的Hash-to-node表。(这张表在节点发生变化时也同样需要重新分发)

以下SQL有助于显示数据块的属主(master)和拥有者(owner)。这个SQL结合了x$kjbl和x$le表来获得资源名称。如果你对于Oracle锁机制比较熟悉,你可能认识这些缓存融合(cache fusion)锁(以前的PCM锁)的结构。在这里锁类型是BL,id1是block#,id2是file_id。列kjblname2显示的是锁资源的十进制数字格式。

请注意下面的输出:
1. 数据块范围:File 1, block 6360-6376为node 3所掌控同时也属于node 3
2. 数据块范围:File 1,一直到10709数据块为实例0所掌控,属于实例3
3. 从10770开始的下一个数据块范围为实例2所掌控并且属于实例3

还请注意这些输出是从一个还没有remastering操作的数据库中获得的。

REM kjblname2列逗号前第一部分是数据块,第二部分file_id*65536是BL locks
[sourcecode language=”sql”]select kj.*, le.le_Addr from (
select kjblname, kjblname2, kjblowner, kjblmaster, kjbllockp,
substr ( kjblname2, instr(kjblname2,’,’)+1, instr(kjblname2,’,’,1,2)-instr(kjblname2,’,’,1,1)-1)/65536 fl,
substr ( kjblname2, 1, instr(kjblname2,’,’)-1) blk
from x$kjbl
) kj, x$le le
where le.le_kjbl = kj.kjbllockp
order by le.le_addr
/

KJBLNAME KJBLNAME2 KJBLOWNER KJBLMASTER FL BLK LE_ADDR
———————- ————— ———- ———– — —– —————-
[0x18d8][0x10000],[BL] 6360,65536,BL 3 3 1 6360 000000038DF9AB08

[0x18e7][0x10000],[BL] 6375,65536,BL 3 3 1 6375 000000038DFBF818 => case #2
[0x18e8][0x10000],[BL] 6376,65536,BL 3 3 1 6376 000000038DFD3BA0

[0x29d1][0x10000],[BL] 10705,65536,BL 3 0 1 10705 00000005D6FE9230

[0x29d5][0x10000],[BL] 10709,65536,BL 3 0 1 10709 000000038EFBB990
[0x2a12][0x10000],[BL] 10770,65536,BL 3 2 1 10770 000000075FFE3C18

[0x2a18][0x10000],[BL] 10776,65536,BL 2 2 1 10776 000000038EFA8488 => case #1
[0x2a19][0x10000],[BL] 10777,65536,BL 3 2 1 10777 000000038EFB7F90
[0x2a1a][0x10000],[BL] 10778,65536,BL 1 2 1 10778 000000038EFCC318
[/sourcecode]

让我们看一下在实例3上运行3种简单SELECT语句的情况:
1. 一个会话尝试读取数据块file 1,block 10776,但是这个数据块被实例2掌控同时又被实例2拥有(也就是该块现在存在于实例2的buffer cache中)。所以,实例3将给实例2发送一个PR(Protected Read)模式的BL锁要求读取该块。更加复杂的情况我们先忽略掉,实例2将授予实例3一个PR模式锁并且将数据块传送给实例3。显然,这将会有多个GC消息、锁授予和块传递。统计值‘gc remote grants’也会增加。
2. 假设此会话尝试读取数据块file 1, block 6375。此块为实例3掌控同时被实例3拥有,那这时候就不会有额外的GCS/GES过程了,会话直接pin住buffer然后继续工作。
3. 考虑第三种情况。会话尝试读取数据块file 1 block 6374。此块不在任何实例的buffer cache中,但是实例3是这个块的属主,所以只需要消耗少量GC消息和等待而获得本节点的affinity locks,然后将数据块从磁盘读到缓存中来。
在上面的情况2和情况3中,请求者实例同时也是数据块或者块范围的属主节点。在这种情况下,统计值‘gc local grants’增加,这些块上获得的本节点的affinity locks代价较低,这样避免了大量的全局缓存消息。

目前为止一切都很好,但是如果有这样一种情况,实例1在频繁读取一个对象(表、索引等),而其他实例则完全不读取该对象呢(某些应用的代码分区策略或者负载策略就会产生这种现象)?频繁读取一个对象的实例需要为每次OPEN该对象数据块的操作向远程实例请求授权,这合理吗?特别是,当数据块被读进buffer cache,但是又很快从buffer cache中消失的时候呢?如果说频繁读取某个对象的实例又恰恰是这个对象的属主,就像我们在情况2和情况3中看到的那样,这岂不是更好吗?
除此之外,如果数据块即将从缓冲池中移走或者即将被覆盖,就会导致在主实例和其它实例之间的额外消息开销,因为所有权信息需要再被送回块的属主处。

进入对象remastering主题。

Object Remastering
在10g/11g RAC中有很多新功能。其中一个就是对象remastering。这个特性在10gR1中引入,10gR2中得到提高,11g中的得到进一步增强。我注意到其实在9i中也有相应的参数,不过我认为实际上并不能正常工作。
有了对象remastering特性,如果一个对象被某个实例频繁读取,那么这个实例将会成为这个对象的master以此来减少gc remote grants从而提高整个应用的性能。在前面这句话中我用到了“读取(accessed)”这个词,但是实际上并不太贴切,更准确的说法是如果某个实例请求了一个对象上的很多BL锁,那么这个对象将remastered。在完美世界中,即使应用程序没有完善的分区策略,remastering被某个实例频繁读取的对象这样的举措也会因为获取的是更廉价的本地实例亲和锁(affinity locks),从而使RAC开销降到最小。

好吧,我也说了是在完美世界中。实际上这里有几个问题:
1. 重启以后实例不会记住之前的属主情况。这意味着每次重新启动实例都需要重新学习对象的属主情况图。我能预计想要记住属主情况是比较复杂的,但是我认为还是有可能实现的。
2. Remastering的代价并不低。在重配置时实例GRD会被冻结(frozen),而繁忙时这个操作可能需要几秒钟,这将会导致整个实例在这几秒内被冻结。虽然10gR2推出了并行重配置(parallel reconfiguration)(通过_rcfg_parallel_replay初始化参数控制)使用所有LMS进程来完成重配置,但是几秒钟的系统冻结在很多环境中还是完全不能被接受的。
3. 我建议我的客户将LMS进程保持在较低的个数(最多3-5),但是如果降低LMS进程数目,那么实例重配置的有效并行度也会降低。
4. 最后,但并不是最不重要的,对于较繁忙的环境来说,触发remastering事件的默认参数值通常过低,因此导致了频繁的对象remastering。在EBS环境中,对于manager的配置稍稍处理不善就可能导致大量的重配置问题。

Parameters, views and internals
控制remastering行为的有几个参数,并没有很好的文档说明。我的测试结果也并不是非常精确。但是,这些参数还是给了我们一个内部到底如何运作的大体概貌。这些在10gR2版本以前是有效的。而对于11g,整套参数都不一样了,我将另写一篇文章来描述这些改变。

x$object_affinity_statistics维护对象和对象上的OPENs的统计信息。理解OPEN和Buffer Access之间的区别是重要的。如果缓存中的数据块已经处于适当的模式,就没有必要在数据块上打开BL锁,所以如果会话反复存取同一个数据块而不请求额外的BL锁,那么计数就不会增加,因此所谓OPEN就是某一刻的时间帧内对于BL锁的请求计数。

LCK0进程维护着这些对象affinity的统计信息。如果一个实例在比另一实例在某一对象上多打开了50个open(由_gc_affinity_limit参数控制)(译者注:实际上在超过2节点的RAC中,该参数的意思是如果一个实例比环境中其它所有实例访问某一个对象的总和还要多50),那么该对象将成为remastering候选者。该对象被放入队列,LMD0进程读取队列,开始GRD冻结。LMON进程协同LMS进程一起执行buffer cache locks的重配置。所有的这些动作都可以在LMD0/LMON trace文件中找到。初始化参数_gc_affinity_time控制队列的检查间隔,以确认remastering是否要触发,默认值是10分钟。

现在,你不愿看到无论哪个对象都能成为候选者而发生remastering,也就是说,如果仅仅是实例1在某对象上打开了101个BL锁而实例2打开了50个BL锁,那么你不想触发该对象的remastering。只有那些有很高的BL锁请求的对象才应该被放入队列并被remastering。此阀值被另一个参数_gc_affinity_minimum控制,只有超过该参数定义的 “每分钟动态affinity活动的最小数量”的对象才会成为候选者而发生remastering。默认值是2500,我认为这在繁忙的系统中有些低。(译者注:在11g中,默认值是1500,更低)
LMD0 trace文件中的以下几行表示LMD0进程正在读取请求队列:

* kjdrchkdrm: found an RM request in the request queue
  Transfer pkey 6589904 to node 3
*** 2009-10-12 11:41:20.257

How bad can it get?
Remastering问题发生时会影响性能。以下AWR报告显示了DRM重配置问题导致的实例冻结。同样类型的冻结在其它的所有节点上也都可以看见。gc buffer busy等待只是DRM冻结的副作用(不是总有,但是在这个case是这样)。

Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~                                        wait   Call
Event                                 Waits    Time (s)   (ms)   Time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
gc buffer busy                    1,826,073     152,415     83   62.0    Cluster
CPU time                                         30,192          12.3
enq: TX - index contention           34,332      15,535    453    6.3 Concurrenc
gcs drm freeze in enter server       22,789      11,279    495    4.6      Other
enq: TX - row lock contention        46,926       4,493     96    1.8 Applicatio

在同一时刻,DRM大量发生,导致了重复的DRM冻结、实例重配置,从而引发严重的性能问题。

* received DRM start msg from 2 (cnt 5, last 1, rmno 404)
Rcvd DRM(404) Transfer pkey 1598477 from 3 to 2 oscan 1.1
Rcvd DRM(404) Dissolve pkey 6100030 from 2 oscan 0.1
Rcvd DRM(404) Dissolve pkey 5679943 from 2 oscan 0.1
Rcvd DRM(404) Transfer pkey 6561036 from 0 to 2 oscan 1.1
Rcvd DRM(404) Transfer pkey 5095243 to 2 oscan 0.1
...

A small test case
我们来看一个测试,观察一下DRM的产生。使用了索引读路径的查询从一个大索引中读取了几乎所有数据块。
[sourcecode language=”sql”]Session #1:
select data_object_id from dba_objects where object_name=’WMS_N1′;
DATA_OBJECT_ID
————-
6099472

REM 还没有affinity统计信息
select * from x$object_affinity_statistics where object=6099472;
no rows selected.

REM 执行高代价的查询语句
select /*+ index(a WMS_N1) */ count(*) from big_table1 a;

Session #2: 观察DRM表:
REM DRM字段现在是409,。我们将持续观察这个数值。在这个视图中还有其它比较有趣的字段。
select drms from X$KJDRMAFNSTATS;
DRM
—-
409

REM 观察到自从会话#1开始运行在该索引上已经有23442个OPENs
select * from x$object_affinity_statistics where object=6099472;
ADDR INDX INST_ID OBJECT NODE OPENS
—————- ———- ———- ———- ———- ———-
FFFFFFFF7C05BFA8 14 1 6099472 1 23442

REM 该对象上还没有发生mastering
select * from v$gcspfmaster_info where object_id=6099472;
no rows selected

REM 几秒后,OPENs计数从23442上升到33344
select * from x$object_affinity_statistics where object=6099472;
ADDR INDX INST_ID OBJECT NODE OPENS
—————- ———- ———- ———- ———- ———-
FFFFFFFF7C05BFA8 16 1 6099472 1 33344

REM该对象上还没有发生mastering
select * from v$gcspfmaster_info where object_id=6099472;
no rows selected

REM 让人诧异,会话#1还在运行,OPENs计数忽然清零即使DRM还未发生过
REM OPENs从0又升到1229因为会话#1还在运行
ADDR INDX INST_ID OBJECT NODE OPENS
—————- ———- ———- ———- ———- ———-
FFFFFFFF7C05BFA8 0 1 6099472 1 1229

REM 大约10分钟以后,remastering发生了。DRMS从409上升到411。
select drms from X$KJDRMAFNSTATS;
DRM
—-
411

REM 该索引的remastering发生了。现在该对象的属主是0,也就是实例1
select * from v$gcspfmaster_info where object_id=6099472;
FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
———- ———- ————– ————— ————
0 6099472 0 32767 1

REM OPENs还在上升,但是remastering已经发生了。
select * from x$object_affinity_statistics where object=6099472;
ADDR INDX INST_ID OBJECT NODE OPENS
—————- ———- ———- ———- ———- ———-
FFFFFFFF7C05AF78 2 1 6099472 1 42335
FFFFFFFF7C05AF78 3 1 6099472 2 1

REM LMON trace文件也指出pkey的传递。注意pkey和object_id是相同的。
*** 2010-03-23 10:41:57.355
Begin DRM(411) – transfer pkey 6099472 to 0 oscan 0.0
ftd received from node 1 (4/0.30.0)
all ftds received

REM 几秒后,OPENs被再次重置。
select * from x$object_affinity_statistics where object=6099472;
ADDR INDX INST_ID OBJECT NODE OPENS
—————- ———- ———- ———- ———- ———-
FFFFFFFF7C05BFA8 0 1 6099472 1 7437

REM 属主仍然是实例1。
select * from v$gcspfmaster_info where object_id=6099472;
FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
———- ———- ————– ————— ————
0 6099472 0 32767 1[/sourcecode]

我们的测试表明,该索引上发生了大量的BL锁请求,之后对象被remastering。

Undo and affinity
回滚段的Mastering和其它段不同。对于非回滚段而言,一个段上的所有数据块通过哈希算法被分散在各个实例间。只有在经过大量的BL锁请求以后,段才会被mastering。但是对于回滚段而言,激活了一个回滚段的实例立刻成为该段的属主。这是合乎情理的,因为在大多数情况下回滚段将会被打开这个segment的实例使用。初始化参数_gc_undo_affinity控制这种动态undo remastering动作是否发生。

因为回滚段没有真正的object_id,所以使用4294950912作为虚拟object_ids的基准值。比如说,回滚段1(usn=1)的object_id是4294950913,回滚段2(usn=2)的object_id就是4294950914,依次类推(4294950912 = power(2,32) – power (2,14) = xFFFFC000)。

[sourcecode language=”sql”]select objecT_id, object_id-4294950912 usn, current_master, previous_master,
remaster_cnt from v$gcspfmaster_info where object_id>4294950912;

OBJECT_ID USN CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
———- ———- ————– ————— ————
4294950913 1 0 32767 1
4294950914 2 0 32767 1
4294950915 3 0 32767 1
4294950916 4 0 32767 1
4294950917 5 0 32767 1
4294950918 6 0 32767 1
4294950919 7 0 32767 1
4294950920 8 0 32767 1
4294950921 9 0 32767 1
4294950922 10 0 32767 1
4294950923 11 1 32767 1
4294950924 12 1 32767 1
4294950925 13 1 32767 1

REM 注意usn 0在两个实例中都存在,这是系统回滚段。
REM 下面结果显示,头10个回滚段被node1掌控,而接下来的3个被实例2掌控。
select inst_id, usn, gets from gv$rollstat where usn <=13 order by inst_id, usn;
INST_ID USN GETS
———- ———- ———-
1 0 3130
1 1 108407
1 2 42640
1 3 43985
1 4 41743
1 5 165166
1 6 43485
1 7 109044
1 8 23982
1 9 39279
1 10 48552
2 0 4433
2 11 231147
2 12 99785
2 13 1883[/sourcecode]

我没有成功试验出触发下一次回滚段remastering。我创建了一个活动事务在一个节点上产生了200K回滚数据块,然后另外一个节点在读这个表,我观察到在回滚数据块上有大量等待。但是我没有发现这个回滚段上有任何remastering事件。无法确认为什么没有产生,也许是回滚段remastering的条件有所不同吧。

译者注:回滚段的remastering是不会因为另外一个节点对于回滚段有大量读取而发生的,只有在某个实例失效,然后负责进行实例恢复的另外那个实例会暂时的成为这些回滚段的master,这是为了进行实例恢复的需要,在恢复完毕以后所有的undo buffers都会被flush到磁盘上。

PS:我能够使用后面将描述的lkdebug命令手动remaster回滚段,所以oracle也应该可以自动remaster回滚段,只是可能还有一个其它条件也必须满足。

[sourcecode language=”sql”]select * from v$gcspfmaster_info where object_id=431+4294950912;
FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
———- ———- ————– ————— ————
0 4294951343 0 32767 1

Oradebug lkdebug –m pkey 4294951343[/sourcecode]

* kjdrchkdrm: found an RM request in the request queue
  Transfer pkey 4294951343 to node 1
*** 2010-03-24 12:47:29.011
Begin DRM(520) - transfer pkey 4294951343 to 1 oscan 0.1
 ftd received from node 0 (4/0.31.0)
 all ftds received

[sourcecode language=”sql”]select * from v$gcspfmaster_info where object_id=431+4294950912;
SQL> /
FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
———- ———- ————– ————— ————
0 4294951343 1 0 2[/sourcecode]

我不是在劝你们应该去修改这些隐含参数。只是要去理解这些参数,如果你们碰到诸如’gc remaster’, ‘gcs freeze for instance reconfiguration’这样的等待事件,那么应该知道是不是因为默认值太低了。跟技术支持沟通尝试是否能够调整。

Manual remastering
你可以使用oradebug命令来手动remaster一个对象:
[sourcecode language=”sql” light=”true”]oradebug lkdebug -m pkey[/sourcecode]

这会将一个对象remaster请求放入队列。LMD0和LMON进程会完成这个请求。

*** 2010-01-08 23:25:54.948
* received DRM start msg from 1 (cnt 1, last 1, rmno 191)
Rcvd DRM(191) Transfer pkey 6984154 from 0 to 1 oscan 0.0
 ftd received from node 1 (8/0.30.0)
 ftd received from node 0 (8/0.30.0)
 ftd received from node 3 (8/0.30.0)

当前属主是从0开始计数的。

[sourcecode language=”sql”]select * from v$gcspfmaster_info where object_id=6984154;
SQL> /
FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
———- ———- ————– ————— ————
0 6984154 1 0 2

SQL> oradebug lkdebug -m pkey 6984154
Statement processed.

SQL> select * from v$gcspfmaster_info where object_id=6984154;

FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
———- ———- ————– ————— ————
0 6984154 2 1 3[/sourcecode]

Summary
总结一下,remarstering是个很棒的功能。不过遗憾的是,我们有时候会成为它负面效果的受害者。所以,如果你碰到remastering引起的问题,不要直接就禁用它,而是应该去看看能否调优那些参数从而控制remastering事件。如果你仍然想完全禁用DRM,那么我建议设置_gc_affinity_limit和_gc_affinity_minimum参数到一个较高值,比如说1千万。将参数_gc_affinity_time设置为0也可以完全禁用DRM,但是这也意味着再也无法手工remaster对象了。另外,Arup也提到如果DRM被禁用那么x$object_affinity_statistics表也不会再被维护。

再次提醒,这些是隐含参数。在你修改这些参数之前确认Oracle Support同意你的举动。

Update 1:
从11g开始,affinity管理更名为policy管理(策略管理)。比如说,x$object_affinity_statistics表改名为x$object_policy_statistics,与之相似的,初始化参数也发生了改变:参数_gc_affinity_limit改名为_gc_policy_limit;参数_gc_affinity_time改名为_gc_policy_time;出现了一个新的视图v$policy_history,其中所有policy_event = ‘initiate_affinity’的记录都是与DRM事件相关的。
本blog的其它部分仍然没问题,除了默认的_gc_policy_limit参数值降低为1500,这意味着,在理论上,11g可能会产生更多的DRM事件。
[sourcecode language=”sql”] 1* select * from v$policy_history
INST_ID POLICY_EVENT DATA_OBJECT_ID TARGET_INSTANCE_NUMBER EVENT_DATE
———- ——————– ————– ———————- ——————–
2 glru_on 0 1 10/15/2010 10:58:28
2 glru_on 0 1 10/15/2010 11:21:32
2 initiate_affinity 74809 1 10/15/2010 13:27:44
[/sourcecode]

【非常感谢Arup NandaMichael Möller(M2)校对这篇blog,他们大量参与了我的讨论。但是,如果这篇文章中有什么错误那么全是我个人的责任。】
这篇文章的pdf格式可以此Dynamic_remastering_RAC_orainternals下载.

Slide of Load Balancing & Failover

这次在2010数据库技术大会上的演讲主题是 – RAC环境中的负载均衡和失效接管。基本上是概念性的东西,自然在演讲过程中也或多或少分享了自己的实践经验。

周六的早上9点开始,第一场演讲就能有这么多喜爱技术的人来捧场,实在是让人感动。几乎要为自己挣扎数次才起床的举动而感到羞愧。

有兴趣的朋友可以在Slideshare上查看这次演讲的ppt。

Issues when Add Nodes into RAC 10g

近期在客户处将原先的4节点RAC扩充到8节点。期间碰到一些问题,总结一下。

系统环境:
Redhat Enterprise Server 4,Oracle RAC 10.2.0.4,OCFS2

一。现象:
往CRS中添加节点时运行rootaddnode.sh会报PRKC-1044错误。
PRKC-1044 – FAILED TO CHECK REMOTE COMMAND EXECUTION

原因:
在配置ssh对等性的时候,设置的passphrase非空。

解决方法:
重新配置ssh对等性,在Enter passphrase (empty for no passphrase): 时直接回车,不要输入任何密码。

二。现象:
在使用dbca往RAC中添加新节点时报TNS-04602错误。
TNS-04414: File Error caused by: TNS-04602: Invalid syntax error: Expected “LITERAL” before or at…

原因:
数据库中没有设置remote_listener参数。

解决方法:
[sourcecode language=”sql” light=”true”]alter system set remote_listener=’LISTENERS_RAC’ scope=both;[/sourcecode]

三。总结
分别使用CRS_HOME和ORACLE_HOME中的addNode.sh脚本往CRS和RAC中添加节点是方便高效的。

How to change private interface in 10g cluster

如果要修改Private Interface的实际IP地址,必须要在操作系统级别修改,比如通过ifconfig命令以及修改/etc/hosts文件等,而为了避免发生node evictions,需要保证CRS stack down。在修改完IP地址以后,再重新让CRS stack up,才可以使用oifcfg命令修改保存在OCR中的信息。

在10gR2以前起停CRS Stack使用init.crs。

#init.crs stop
#init.crs start

在10gR2以后可以使用crsctl命令。

#crsctl stop crs
#crsctl start crs

1. 检查当前的网络资源配置

% $ORA_CRS_HOME/bin/oifcfg getif 

2. 删除原先的Private Interface设置

% $ORA_CRS_HOME/bin/oifcfg delif –global eth1

3. 添加新的Private Interface设置(此处例子仅仅修改subnet,如果修改了eth1,就是修改了interface name)

% $ORA_CRS_HOME/bin/oifcfg setif –global eth1/192.168.1.0:cluster_interconnect 

4. 再次检查网络资源配置确认已经修改成功

% $ORA_CRS_HOME/bin/oifcfg getif 

5. 重新启动数据库实例,以确认RAC使用了正确的Private Interface作Cache Fusion。在告警日志中检查如下输出:

Cluster communication is configured to use the following interface(s) for this instance
192.168.1.1

How to resolve ORA-01034 when RAC failover

今天在客户处测试Oracle 9.2.0.8 on HP-UX IA64的RAC Failover功能,遇到ORA-01034错误。

表现为:
当关闭RAC环境的某一个实例之后(无论是shutdown abort还是shutdown immediate),再用远程客户端通过tns连接RAC Service都会间歇性报ORA-01034错误。

$ sqlplus system/oracle@prod 

SQL*Plus: Release 9.2.0.8.0 - Production on Tue Nov 17 20:52:09 2009

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

ERROR:
ORA-01034: ORACLE not available
ORA-27101: shared memory realm does not exist
HPUX-ia64 Error: 2: No such file or directory

客户端的TNS配置是很常规的客户端failover。

PROD  =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = VIP1)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = VIP2)(PORT = 1521))
      (LOAD_BALANCE = yes)
    )
    (CONNECT_DATA =
      (SERVICE_NAME = prod)
      (FAILOVER_MODE=
       (TYPE=SELECT)
       (METHOD=BASIC))
    )
  )

纳闷许久,仔细检查服务器端的listener.ora配置,才发现设置了GLOBAL_DBNAME,这是对于还没有往本地监听动态注册服务名功能的Oracle8和Oracle7才需要设置,在Oracle9i之后,如果设置了该参数,将会导致Failover失败。

将listener.ora中的配置从:

SID_LIST_LISTENER_PROD2 =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME=prod)
      (ORACLE_HOME = /oracle/product/9.2)
      (SID_NAME = prod2)
    )
  )

修改为:

SID_LIST_LISTENER_PROD2 =
  (SID_LIST =
    (SID_DESC =
      (ORACLE_HOME = /oracle/product/9.2)
      (SID_NAME = prod2)
    )
  )

再次测试Failover,一切正常。

结论:
1. 对于监听依然存在,然后数据库实例关闭的情况,必须是在监听中动态注册的服务,才可以实现Failover。
2. GLOBAL_DBNAME会影响Failover。

How to identify the cluster name

在为RAC环境配置database control的时候,会被问及cluster name,当然我们知道默认安装的Oracle Cluster Name就是crs,但是如何确认到底CRS的名字是什么呢?

[oracle@dbserver1 oracle10g]$ emca -config dbcontrol db -cluster -EM_NODE dbserver1 -EM_SID_LIST intertol2,intertol3,intertol4

STARTED EMCA at Jul 27, 2009 4:20:25 PM
EM Configuration Assistant, Version 10.2.0.1.0 Production
Copyright (c) 2003, 2005, Oracle.  All rights reserved.

Enter the following information:
Database unique name: intertol
Database Control is already configured for the database intertol
You have chosen to configure Database Control for managing the database intertol
This will remove the existing configuration and the default settings and perform a fresh configuration
Do you wish to continue? [yes(Y)/no(N)]: Y
Listener port number: 1521
Cluster name:

实际上Oracle提供了一个实用程序cemutlo来获取cluster name。

[oracle@dbserver1 ~]$ $ORA_CRS_HOME/bin/cemutlo -h
Usage: /u01/app/oracle/product/crs/bin/cemutlo.bin [-n] [-w]
        where:
        -n prints the cluster name
        -w prints the clusterware version in the following format:
                 ::

[oracle@dbserver1 ~]$ cemutlo -n
crs

另外还有使用ocrdump命令或者ocrconfig命令来间接获得cluster name的方法,详细参看《怎么查安装CRS时设置的cluster name》