Oracle RAC 配置和测试
问题描述
RAC 是一种准高可用性配置,能够提供 RAC 实例中各节点间的负载平衡、Failover 和数据库扩展。它提供了一种向数据库中添加节点、增加容量和提高性能的方法。
什么是 Oracle9i RAC?
Oracle9i RAC 是一个 Oracle 数据库,它允许两个或更多个实例通过群集技术访问共享的数据库。一个群集是一组计算机(或节点),它们一起工作,执行同一项任务。为支持这种体系结构,需要通过高速互连将数据库实例的两个或更多个宿主计算机链接在一起,以构成群集。互连是一种物理网络,用作群集各节点之间的通信手段。群集功能由操作系统或第三方软件(如 Veritas)提供,因此您需要确保群集或高可用性子系统与 RAC 兼容。
Oracle9i RAC 安装
大多数的 Failover 和负载平衡工作由 Oracle 提供的 JDBC 驱动程序来完成,并且这些工作的实现方式对于 WLS 是不可知的。因此,WLS 的主要任务是确保将 JDBC 配置为向 Oracle JDBC 驱动程序传递适当的参数。此外,还有一个 RAC 组件,该组件使用的群集和事务恢复功能是数据库 RAC 实现的组成部分。
尽管 RAC 也支持负载平衡和恢复功能,但用户遇到的大多数问题是 Failover 时的行为。由于 RAC 实现了 MultiPool 功能,WLS 无法控制与 Failover 有关的任何延时,甚至无法确认何时需要进行 Failover。Failover 的原因不同,Failover 行为也不同。如果 Oracle 数据库发生故障(Oracle 节点或 DB 终止运行,但操作系统仍在运行),正常情况下 Failover 很快就会完成。不过,如果发生的是硬件/操作系统故障,则由于 TCP 延时(所有 WLS MultiPool 实现都将出现同样的延时),Failover 可能需要一些时间才能完成。
用户的期望是获得可无缝、即时地进行 Failover 的高可用性系统。当然,鉴于以上所列的限制,这种期望无法实现。
(English)
RAC 要依靠操作系统群集技术来提供数据完整性所需的磁盘共享功能。该技术可以由第三方(如 Veritas,针对 SUN 平台)提供,或从操作系统/硬件供应商处获得。
典型问题
用户需要更深入了解以下内容:
JDBC 驱动程序的配置
期望能够提供哪些服务
如何在 WLS 内利用这些服务
故障排除
请注意,并非下面所有任务都需要完成。有些问题仅通过执行几项任务就可以解决。
快速链接
为什么发生此问题?
配置基础
测试 RAC 配置
基本调试
外部资源
为什么发生此问题?
发生问题的原因多种多样,以下是最常见的原因:
请求了驱动程序不支持的服务
误解 RAC 提供的服务
JDBC 配置问题
最常见的驱动程序问题是驱动程序不支持请求的服务(例如,Oracle 9.2.0.4 不支持“负载平衡”)。
也可能是对高可用性的期望所致,也就是期望获得一经发现错误便立即做出反应的系统,如在“下一次击键”时即可识别故障的不间断 (Tandem Copywrite) 系统。在此情况下无法实现这种期望,因为 Failover 的主要机理是 IP 故障。
因此,确定是否需要转到另一 RAC 节点的时间与确定终端系统不可用的时间可能一样长。这是由 TCP 设置决定的。举例来说,Solaris TCP 的标准超时设置是 4 分钟。该设置通过 ndd 来管理。
发生问题的另一个原因是期望能够恢复所有事务,但实际上只能恢复写入磁盘(prepare/commit 阶段)的事务。
返回页首
配置基础
假定有以下 Oracle RAC 配置:
Sid = slrac
SLRAC =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.18.137.231)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.18.137.230)(PORT = 1521))
(LOAD_BALANCE = yes)
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = slrac.bea.com)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
)
)
)
SLRAC2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.18.137.230)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = slrac.bea.com)
(INSTANCE_NAME = slrac2)
)
) SLRAC1 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.18.137.231)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = slrac.bea.com)
(INSTANCE_NAME = slrac1)
)
)
WLS JDBC URL 的配置如下:
jdbc:oracle:thin:@(description=(address_list= (address=(host=172.18.137.231) (protocol=tcp)(port=1521))(address=(host=172.18.137.230)(protocol=tcp) (port=1521)) (load_balance=yes)(failover=yes))(connect_data=(service_name= slrac.bea.com)))
正常情况下,部署时会看到以下内容:
Connection successful on:myserver
at mydomain> JDBC Connection Pools> RACTest
(备注:应设置 TestOnReserve)
在要求安装 thin 驱动程序的环境中(配置上的简易所带来的便利胜过了安装 Oracle 客户端所带来的不便),Java thin 将支持作为 RAC 成套功能一部分的组播功能。此外,请与 Oracle 确认所请求的功能可与所使用的 JDBC 驱动程序兼容。
此外,Oracle 的某些 RAC 配置最佳惯例并不是 BEA 建议的做法。Oracle 建议每个监听器均使用全局和本地 DB,因而在上述配置中,SLRAC1 的监听器可以识别 SLRAC,而 SLRAC 的监听器可以识别 SLRAC1。BEA 建议监听器只识别本地实例。也就是说,SLRAC 只识别 SLRAC 实例。BEA 建议做此项改动是为了便于 Failover。
重要的是要了解:在使用 RAC 时,Oracle 驱动程序会提供由 WLS 提供的 MultiPool 功能(例如,从一个数据库实例向另一个数据库实例 Failover),而 RAC 功能还提供了一定程度的数据完整性,即可以恢复 prepared 的事务。
不允许将 WLS MultiPool 与 RAC 一起使用。请记住,一般情况下 MultiPool 不能与 XA 驱动程序一起使用,而且 MultiPool 尚未获得 RAC 认证。在非 TX 环境中,目前尚未发现 MultiPool 可以与 RAC 一起使用。
返回页首
测试 RAC 配置
要测试 RAC 配置,请执行以下操作:
启动配置为群集 RAC 成员的 Oracle 节点或 Oracle DB 实例。
然后使用下面提供的示例代码进行测试(修改用户 URL 和数据源)。
还可以使用 WLS 控制台的 JDBC 连接池中的 TestPool 工具来测试池。
备注:从 WLS 的角度来看,RAC 是以单一连接池和单一数据源形式配置的。
测试(执行控制台中的 Testpool)后,关闭一个节点。
一切应会运行良好。
关闭另一个节点。
将会发生故障。
开启一个节点。
一切应会运行良好。
在 Oracle 端进行 DB 控制。
请注意,除配置较复杂外,RAC 调试(下文中论述)的执行步骤与任何其它 JDBC 问题的调试步骤均相同。您应该先获得 jdbc.log 和配置信息,在控制台中测试池,然后使用数据源来测试池。
如果出现错误,请检查 JNDI 树以确认数据源是否可用。
返回页首
基本调试
将此问题作为标准 JDBC 连接池问题来对待。
确认 config.xml
以下是配置 JDBC 连接来使用 RAC 的示例代码:
DriverName="oracle.jdbc.driver.OracleDriver" Name="RACTest"
Password="{3DES}SnVOJbMRf3M=" Properties="user=mks" Targets=""
TestConnectionsOnCreate="true" TestConnectionsOnRelease="true"
TestConnectionsOnReserve="true"
TestTableName="SQL SELECT 1 FROM DUAL" URL="jdbc:oracle:thin:@(description=(address_list= (address=(host=172.18.137.231) (protocol=tcp)(port=1521))(address=(host=172.18.137.230)(protocol=tcp) (port=1521)) (load_balance=yes)(failover=yes))(connect_data=(service_name= slrac.bea.com)))"/>
Name="RACTest1" PoolName="RACTest" Targets=""/>
安装一个简单的、可以对 RAC 数据库进行测试的 Java 应用程序。
提供了以下示例:
使用该示例前的准备:
设置环境(例如 user_projects/domains/myserver)
UNIX 系统:>../setEnv.sh
Windows 系统:setEnv
将 CLASSPATH 设置为指向 racTest1.class
(例如,设置 CLASSPATH=.;%CLASSPATH%。如果是 UNIX 系统,请设置 export CLASSPATH=.:$CLASSPATH)
还请注意,本示例只测试基本 sql 语句,不测试事务。
Sample Test Code- Standard Data Source test
//package examples.jdbc.datasource;
import java.sql.*;
import java.util.*;
import javax.naming.*;
public class racTest1 {
public static void main(String argv[])
throws Exception
{
java.sql.Connection conn = null;
java.sql.Statement stmt = null;
try {
// ============== Make connection to database ==================
// Obtain a Datasource connection from the WebLogic JNDI tree.
Context ctx = null;
// Put connection properties in to a hashtable.
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL,
"t3://mks4:6151");
// Get a context for the JNDI look up
System.out.println("before init ctx connection...\n");
ctx = new InitialContext(ht);
System.out.println("after init ctx connection...\n");
javax.sql.DataSource ds
= (javax.sql.DataSource) ctx.lookup ("RACTest1");
conn = ds.getConnection();
System.out.println("Making connection...\n");
// execute some SQL statements to demonstrate the connection.
stmt = conn.createStatement();
try {
stmt.execute("drop table empdemo");
System.out.println("Table empdemo dropped.");
} catch (SQLException e) {
System.out.println("Table empdemo doesn't need to be dropped.");
}
stmt.execute("create table empdemo (empid int, name varchar(30), dept int)");
System.out.println("Table empdemo created.");
int numrows = stmt.executeUpdate("insert into empdemo values (0, 'John Smith', 12)");
System.out.println("Number of rows inserted = " + numrows);
numrows = stmt.executeUpdate("delete from empdemo where empid = 0");
System.out.println("Number of rows deleted = " + numrows);
} catch (Exception e) {
System.out.println("Exception was thrown: " + e.getMessage());
} finally {
try {
if (stmt != null)
stmt.close();
if (conn != null)
conn.close();
} catch (SQLException sqle) {
System.out.println("SQLException during close(): " + sqle.getMessage());
}
}
}
}
测试池
树中 JNDI 条目中的数据源 - 注意 RACTest1(本示例中的 RAC 数据源)
确保数据库已启动并正在运行。
查看启动脚本以确定 JDBC 驱动程序。
启动脚本中的 CLASSPATH 应指向 JDBC 驱动程序。
指向的应该是 ojdbc14.jar,它应在 weblogic jar 之前。
返回页首
外部资源
Masking Failures with Transparent Application Failover (TAF)
返回页首
已知问题
您可以定期查看所用 WLS 版本的“Release Notes”,了解 Service Pack 中的“Known Issues”或“Resolved Issues”的详细信息及浏览相关问题。方便起见,下面提供了这些发行说明的链接:
WLS 8.1 Release Notes (English)
使用搜索功能也可以搜索到“Release Notes”,还可以搜索到其它支持解决办法及与 CR 有关的信息,如需要更多帮助?中所提到的内容。如果客户签订了技术支持合同,则可以登录 ,登录后会看到为 Solutions 和 Bug Central 提供的 Browse portlet,可在其中按产品版本浏览最新提供的 CR。
需要更多帮助?