|
本帖最后由 dbathink 于 2013-10-7 23:31 编辑
1、大家在安装部署Oracle 11g RAC中都碰到了什么问题,如何规避?
在RAC的第二个节点执行第二个脚本时经常会报错
如何规避:1、详细阅读官方文档 2、利用runcluvfy.sh工具检查CRS环境 3、注意VIP
2、Oracle 11g RAC的SCAN(单一客户端访问称)有什么作用?一定要用SCAN吗?为什么?
Oracle 11g R2引入了SCAN“单一客户端访问名称”,它解析为在DNS或GNS中注册的3个不同IP地址。在安装Oracle Grid
Infrastructure期间,Oracle创建3个SCAN监听器和SCAN VIP。如果没有使用GNS(网格名称服务器),那么在安装Oracle Grid
Infrastructure之前,必须在DNS中注册SCAN。在发生故障时,Oracle将VIP和监听器故障转移到另一个节点。每个数据库实例都使
用数据库初始化参数REMOTE_LISTENER将自已注册的本地监听和SCAN监听器,因为这是SCAN监听器了解数据库实例位置的唯一途径
。SRVCTL实用工具可用于管理和监控集群中的SCAN资源。
SCAN简化了客户端连接管理,这是因为即使当客户端的目标数据库被转移到集群中的不同节点时,也不需要改变客户端连接字
符串。在Oracle 11g R2之前,除了修改服务之外,没有其它方法能够告客户端连接:它希望使用Oracle RAC服务连接的数据库实
例已经被转移到另一个集群节点。SCAN允许在不修改Orace RAC服务器的情况下故障转移动发生移动的数据库实例。
以下步骤解释一个客户端如何用SCAN连接到集群中的数据库:
(1)TNS层从域名服务器或网络名称服务器获取SCAN的IP的地址,然后它实现负载均衡,并在IP地址之间实现故障转移。
(2)SCAN监听器现在知道集群中的数据库,并将连接重新导向目标数据库节点VIP。
管理SCAN
(1)显示SCAN VIP的状态(root用户下操作)
$GRID_HOME/bin/srvctl status scan
(2)显示SCAN监听器的状态(root用户下操作)
$GRID_HOME/bin/srvctl status scan_listener
(3)显示SCAN的现在配置(root用户下操作)
./srvctl config scan
(4)添加一个SCAN(root用户下操作)
$GRID_HOME/bin/srvctl add scan -n prod-scan
(5)删除一个SCAN(root用户下操作)
$GRID_HOME/bin/srvctl remove scan
(6)添加一个SCAN监听器
$GRID_HOME/bin/srvctl add scan_listener
(7)删除一个SCAN监听器
$GRID_HOME/bin/srvctl remote scan_listener
(8)修改一个SCAN监听器端口
$GRID_HOME/bin/srvctl modify scan_listener -p <port_number>
不一定要用SCAN,因为不用SCAN,只是在客户端配置的时侯麻烦一点,利用SCAN只是简化了客户端连接管理。
3、如何设置RAC的BALANCE(负载均衡)?它的优缺点是什么?平时生产库上开BALANCE吗?为什么?
负载均衡指的是连接的负载均衡,也就是一个新应用连接进来的时候,会选择RAC环境中的哪个主机。这里先介绍一个9i中利初始参数、listener.ora与tnsnames.orag来做负载均衡的案例,首先配置参数:
rac1.local_listener='(address=(protocol=tcp)(host=dbrac01)(port=1521))'
rac1.remote_listener=(address=(protocol=tcp)(host=dbrac02)(port=1521))'
rac2.local_listener='(address=(protocol=tcp)(host=dbrac02)(port=1521))'
rac2.remote_listener=(address=(protocol=tcp)(host=dbrac01)(port=1521))'
启动监听以后,只要监听参显示2节点即可
在tnsnames.ora的配置中,只要连接的是整个数据库的服务名,不是实例名,而且增加load_balance=on与failover=on即可。
-------------Oracle10g以后,RAC连接上的负载均衡类似9i连接负载均衡。这里介绍另外一种配置连接的负载均衡的案例,首先,d tnsnames.ora中配置如下信息,注意这里的主机
对应的都是VIP:
Listeners_RAC =
(address_list =
(address=(protocol=tcp)(host=dbrac01-vip)(port=1521))
(address=(protocol=tcp)(host=dbrac02-vip)(port=1521))
(address=(protocol=tcp)(host=dbrac03-vip)(port=1521))
(address=(protocol=tcp)(host=dbrac04-vip)(port=1521))
)
然后配置参数:
*.remote_listener='Listeners_RAC'
在启动监听以后,可以看到监听器上的4个instance:
Service "RAC" has 4 instance(s).
Instance "rac01",status READY, has 2 handler(s) for this service...
Instance "rac02",status READY, has 1 handler(s) for this service...
Instance "rac03",status READY, has 1 handler(s) for this service...
Instance "rac04",status READY, has 1 handler(s) for this service...
看到如上信息,表示监听器正常,然后再配置tnsnames.ora,添加如下的内容:
RAC=
(descripation =
(load_balance = on)
(address=(protocol=tcp)(host=dbrac01-vip)(port=1521))
(address=(protocol=tcp)(host=dbrac02-vip)(port=1521))
(address=(protocol=tcp)(host=dbrac03-vip)(port=1521))
(address=(protocol=tcp)(host=dbrac04-vip)(port=1521))
(connect_data =
(server = dedicated)
(service_name = rac)
)
)
优点是:可以分担其它节点的负载,横向扩展。 缺点:内网心跳会成为瓶劲,会有GCS等待。
平时生产库不开rebalance,大部分RAC做HA的故障切换功能。
4、RAC中非常重要一个概念CACHE FUSION(缓冲区融合),它有什么作用?
Cache Fusion就是通过互联网络在集群内各节点的SGA之间进行块传递,以避免首先将块推送到磁盘,然后再重新读入其他实例的缓存中这样一种低效的实现方式(OPS的实现)。当一个块被读入RAC环境中某个实例的缓存时,该块会被 赋予一个锁资源(与行级锁不同),以确保其他实例知道该块正在被使用。之后,如果另一个实例请求该块的一个副本,而该块已经处于前一个实例的缓存内,那么该块会通过互联网络直接被传递到另一个实例的SGA。如果内存中的块已经被改变,但改变尚未提交,那么将会传递一个CR副本。这就意味着只要可能,数据块无需写回磁盘即可在各实例的缓存之间移动,从而避免了同步多实例的缓存所花费的额外I/O。很明显,不同的实例缓存的数据可以是不同的,也就是在一个实例要访问特定块之前,而它又从未访问过这个块,那么它要么从其他实例cache fusion过来,或者从磁盘中读入。
5、RAC经常出现的等待事件是什么?您是如何处理的?
全局热块冲突是RAC平台经常出现的一种等待事件,这种等待如果比较严重的话,会对系统的性能产生十分重大的影响,甚至导致数据库被短时挂住。全局热块冲突和普通的热块冲突类似,普通的热块冲突是在一个单节点上多个会话访问相同的数据块导致的等待事件。如果大量会话访问某个或某些特定的数据块,那么这些数据块被称为热块。相比单实例环境,全局热块冲突的危害更大,因为全局的热块需要在实例间进行传递。严重的全局热块冲突会导致系统性能急剧下降。最典型的案例就是,如果某个应用要对某张表进行大批量的数据插入,而且插入的进程都跑在一个节点上,那么这个系统可能会出现一些buffer busy waits等待事件,不过不会产生很严重的性能问题。如果这个应用负载均衡方式分布在不同的节点上,那么从STATSPACK/AWR报告中,我们可能看到下面的情况:Top 5 Timed Events
Avg %Total
~~~~~~~~~~~~~~~~~~
wait Call
Event Waits Time (s)
(ms) Time Wait Class
------------------------------ ------------ -----------
------ ------ ----------
buffer busy waits 17,149 12,743
743 37.3 Concurrenc
gc buffer busy 21,057 12,328
585 36.1 Cluster
enq: HW - contention 19,571 7,155
366 20.9 Configurat
CPU time 1,253
3.7
gc current block 2-way 207,726 525
3 1.5 Cluste
-------------------------------------------------------------
对于这种情况,需要在应用的底层进行设计。比如有一种很常用的方法,就是在某张表中设计一个INSTANCE_ID字段,在插入数据时,每个实例插入的数据中都带有INSTANCE_ID,然后按照INSTANCE_ID对这张表进行分区,两个实例之间的gc buffer busy争用就会大幅度地减少。下面就是通过这种方式优化后的AWR报告。
Event Waits Time(s) Avg Wait(ms) % Total Call Time Wait Class
CPU time 1,334 92.3
log file sync 554,591 334 1 23.1 Commit
log file parallel write 536,004 106 0 7.3 System I/O
gc cr multi block request 449,571 85 0 5.9 Cluster
wait for scn ack 417,500 73 0 5.1 Other
从上面的报告可以看出,gc buffer busy消失了。
RAC 上解决gc buffer busy的常用方法之一:
对表结构做一个调整,来彻底解决这个问题。我们重新对表进行分区,使之成为一个复合分区表,在这张表上加入一个字段 inst_id,也就是
实例编号,这个字段作为主分区字段,按照这个分区做范围分区后,再设置msg_id的hash分区。调整后的表结构如下:
Create table qstore
(
MSG_ID VARCHAR2(64 BYTE) NOT NULL,
DOCE_ID VARCHAR2(100 BYTE) NOT NULL,
DOC_KEY VARCHAR2(100 BYTE) NOT NULL,
BUS_NAME VARCHAR2(100 BYTE) NOT NULL,
MODULE_NAME VARCHAR2(100 BYTE),
CATEGORY VARCHAR2(64 BYTE),
SUB_CATEGORY VARCHAR2(64 BYTE),
DOC_SIZE NUMBER(11) DEFAULT 0,
CREATE_TIME DATE,
MODIFY_TIME DATE,
EXPIRED_TIME DATE,
DOC_FLAG VARCHAR2(2),
Inst_id number
)
PARTITION BY RANGE(inst_id)
SUBPARTITION BY HASH(msg_id) SUBPARTITIONS 8
(PARTITION p1 VALUES LESS THAN (2)),
(PARTITION p1 VALUES LESS THAN (3));
inst_id 的值就是 插入进程连接到的实例的ID,这样调整后,在1号节点上插入的数据将全部被插入到inst_id=1的分区,插入操作就不会
产生大量的global cache request了。这种做法也是在RAC上解决gc buffer busy 的常用方法之一。
即可以方便通过交换分区的方式对历史数据进行归档,而且可以通过HASH分区来减少buffer busy waiT和 HW锁等待。
|
|