崔华,网名 dbsnake
Oracle ACE Director,ACOUG 核心专家
(【崔华文章系列】已获崔华独家授权在云和恩墨官方微信账号陆续发布,请大家持续关注)
这篇文章详细介绍了 Oracle RAC 环境下的连接管理,分别介绍了什么是 Connect Time Load Balancing、Runtime Connection Load Balancing、Connect Time Connection Failover 和 Runtime Connection Failover,以及里面所涉及到的 TAF、ONS、FCF、FAN、LBA 等诸多知识点。本文主要是针对 Oracle RAC 11gR2 环境下的连接管理,但同时也会对比说明一下 Oracle RAC 10gR2/9iR2,以体现他们之间在连接管理上的差异。
所谓“连接管理”,主要体现在 Load Balancing 和 Failover 两方面。Oracle RAC 11gR2 下的 Load Balancing 和 Failover,根据是否使用了事先已经存在的连接(如连接池中的连接)又分为 Connect Time Load Balancing、Runtime Connection Load Balancing、Connect Time Connection Failover 和 Runtime Connection Failover 这 4 种类型,凡是带上了“Runtime”前缀的,就是指连接已经存在的情况,比如使用了连接池。
一、首先来介绍 Connect Time Connection Failover
Connect Time Connection Failover 是指不从连接池中取得已有连接,而是直接连接 Oracle 数据库时的 Failover。在 Oracle RAC 11gR2 之前,Connect Time Connection Failover 是非常容易实现的,只需要在相关的 tnsnames.ora 中指定多个 vip,同时指定 FAILOVER=ON 就好了。如下所示:
(DESCRIPTION= (FAILOVER=ON) (ADDRESS_LIST= (LOAD_BALANCE=OFF) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC1-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC2-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC3-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC4-vip)(PORT=1521)) ) (CONNECT_DATA=(SERVICE_NAME=RAC10g)) )
这里客户端进程首先会尝试连接 RAC1-vip,如果连不上,则会尝试 RAC2-vip,再连不上,则会继续往下尝试,直到所有出现在 ADDRESS_LIST 中的 vip 地址全部顺序尝试完为止。这种客户端在连接 Oracle 数据库时的 Failover,不仅适用于 RAC 环境,也适用于 Data Guard 环境。如下所示:
DESCRIPTION= (FAILOVER=ON) (ADDRESS_LIST= (LOAD_BALANCE=OFF) (ADDRESS=(PROTOCOL=TCP)(HOST=primary-ip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=standby-ip)(PORT=1521)) ) (CONNECT_DATA=(SERVICE_NAME=service10g)) )
Oracle RAC 11gR2 引入了 SCAN(Single Client Access Name),并且客户端缺省是通过 SCAN 来连接整个 RAC 环境的,如下是 SCAN 的架构图:
如上图所示,如果使用了 DNS 或者 GNS (Grid Naming Service),那么最多可以有 3 个 SCAN VIP 和 3 个 SCAN Listener;如果没有使用 DNS 或者 GNS,而是选择使用 hosts 文件,则只会有 1 个 SCAN VIP 和 1 个 SCAN Listener。
这里假设在 tnsnames.ora 中这样配置:
(DESCRIPTION = (FAILOVER=ON) (ADDRESS = (PROTOCOL = TCP)(HOST = MySCAN)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RAC11g)))
严格意义上说,只有在 RAC 环境有 1 个以上 SCAN VIP 的时候,上述 FAILOVER=ON 才有意义——它表示的是客户端在连接 SCAN VIP 的时候,如果其中的一个 SCAN VIP 连不上,则马上会尝试另外一个 SCAN VIP。
当使用了 hosts 文件来指定 SCAN VIP 的时候,即在整个 RAC 环境只有 1 个 SCAN VIP 的情况下,Failover 其实也存在,只不过这种情况下 Failover 的速度会慢一些。因为当 SCAN VIP 所在的节点宕掉后,SCAN VIP 会和相关的 SCAN Listener 一起整体 Failover 到其他节点,只不过这个 Failover 需要时间,而客户端需要等待这个 Failover 过程完毕后才能重新连上 RAC。
二、接下来介绍 Runtime Connection Failover
Runtime Connection Failover 是指连接已经存在的情况下的 Failover。这个已存在的连接,可能是连接池中正在用的连接,也可能是不通过连接池、直接通过 OCI 客户端(如 sqlplus)连上 Oracle 数据库后的连接。
这种 Runtime Connection Failover,就是指在连接已经存在的情况下,如果 Oracle 数据库端出现了异常的情况(比如 Service 宕了、Instance 崩溃了、Session 断了)而导致已有连接中断,怎样 Failover 的问题。
有两种手段来实现 Runtime Connection Failover,分别为 TAF(Transparent Application Failover)和 FCF(Fast Connection Failover)。
首先来介绍 TAF。TAF 有如下一些知识点需要我们注意:
1、它可以在 client 端的 tnsnames.ora 中的连接串里定义,也可以在 server 端的 service 中定义,只不过 service 端的设置会取代(override)客户端 tnsnames.ora 中的设置:
客户端可以这样设置 TAF:
(DESCRIPTION = (FAILOVER=ON) (ADDRESS = (PROTOCOL = TCP)(HOST = MySCAN)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = Email) (FAILOVER_MODE= (TYPE=select)(METHOD=basic)(RETRIES=180)(DELAY=5)))
Server 端可以这样设置 TAF:
srvctl modify service -d RAC11g -s Email -q TRUE -P BASIC -e SELECT -z 180 -w 5 -j LONG 具体各个参数的含义可参见如下注释:
Usage: srvctl modify service -d <db_unique_name> -s <service_name> [-c {UNIFORM | SINGLETON}] [-P {BASIC|PRECONNECT|NONE}] [-l [PRIMARY][,PHYSICAL_STANDBY][,LOGICAL_STANDBY][,SNAPSHOT_STANDBY]] [-y {AUTOMATIC | MANUAL}][-q {true|false}] [-x {true|false}] [-j {SHORT|LONG}] [-B {NONE|SERVICE_TIME|THROUGHPUT}] [-e {NONE|SESSION|SELECT}] [-m {NONE|BASIC}] [-z <integer>] [-w <integer>] -d <db_unique_name> Unique name for the database -s <service> Service name -c {UNIFORM | SINGLETON} Service runs on every active server in the server pool hosting this service (UNIFORM) or just one server (SINGLETON) -P {NONE | BASIC | PRECONNECT} TAF policy specification -l <role> Role of the service (primary, physical_standby, logical_standby, snapshot_standby) -y <policy> Management policy for the service (AUTOMATIC or MANUAL) -e <Failover type> Failover type (NONE, SESSION, or SELECT) -m <Failover method> Failover method (NONE or BASIC) -w <integer> Failover delay -z <integer> Failover retries -j <clb_goal> Connection Load Balancing Goal (SHORT or LONG). Default is LONG. -B <Runtime Load Balancing Goal> Runtime Load Balancing Goal (SERVICE_TIME, THROUGHPUT, or NONE) -x <Distributed Transaction Processing> Distributed Transaction Processing (TRUE or FALSE) -q <AQ HA notifications> AQ HA notifications (TRUE or FALSE) -h Print usage
2、当 TAF 的TYPE 设置为 select 的时候,单纯 select 操作(不包括 select … for update)可以做到“断点续传”,即单纯的 select 操作在利用 TAF 实现 Failover 后是可以从中断的地方继续往下执行的;3、TAF 对 DML 操作不能做到“断点续传”,即如果一个 transaction 在使用 TAF 实现 Failover 后,该 transaction 不能从中断的地方继续执行,需要再次从头开始执行;4、TAF 仅对使用 OCI 连接的客户端和连接池有效,这里的 OCI 连接可以是在 OCI 连接上的封装,比如 JDBC-OCI driver 就支持 TAF,但 JDBC thin driver 就不支持 TAF(因为 JDBC thin driver 不是基于 OCI 的)。
接下来,在介绍 FCF(Fast Connection Failover)之前,我们必须要先介绍 FAN(Fast Application Notification)。
FAN 是 Oracle RAC 里的一种消息主动通知机制。当 RAC 里出现 service down/up,instance down/up,节点负载变化时,Oracle 数据库都能通过 FAN events 将这些信息发布出去,订阅这些 FAN events 的客户端在第一时间收到这些 FAN events 后就能做出相应的动作来响应这些 FAN events。
FAN events 分为两种,第一种是 FAN HA events,第二种是 LBA events,这里的 LBA 是指 Load Balancing Advisory。
当 RAC 里出现 service down/up、instance down/up 时就会触发 FAN HA events。FAN HA events 的示例如下所示:
Event 1: FAN event type: instance Properties: version=1.0 service=PROD database=PROD instance=PROD1 host=node1 status=down Event 2: FAN event type: service_member Properties: version=1.0 service=ERP database=PROD instance=PROD1 host=node1 status=downEvent 3: FAN event type: service_member Properties: version=1.0 service=ERP database=PROD instance=PROD3 host=node3 status=up
RAC 里节点的负载变化后也会产生 LBA events,LBA events 的示例如下所示:
Event 4: FAN-event type: service_metrics Properties: version=2.0 service=ERP database=PROD instance=PROD1 percent=70 service_quality=GOOD instance=PROD2 percent=30 service_quality=GOOD Event 5 :FAN-event type: service_metrics Properties: version=2.0 service=CRM database=PROD instance=PROD2 percent=30 service_quality=GOOD instance=PROD3 percent=70 service_quality=GOOD
上述 FAN events 可能会通过多种渠道传播出去,这些渠道包括 ONS(Oracle Notification Service),AQ(Advanced Queue),PMON 等。下面是关于 FAN events 架构和传播途径的两张图,它们就直观的说明了 FAN events 的传播途径:
订阅 FAN HA events 的客户端包括:JDBC Implicit Connection Cache, OCI, ODP.NET Connection Pools, Listener, Server Side Callouts 等;
订阅 LBA events 的客户端包括:JDBC Implicit Connection Cache, ODP.NET Connection Pools, Listener,OCI Session Pools 等;
介绍完 FAN,现在可以开始介绍 FCF:FCF 的意思是 Fast Connection Failover,它实际上是客户端通过订阅 FAN HA events 来实现的。如下是两个客户端通过订阅 FAN HA events 来实现 FCF 的例子:
例一:JDBC Fast Connection Failover (FCF)这里的 JDBC 连接是指 JDBC thin 连接。因为 JDBC thin 连接不是基于 OCI 的,所以这种情况下的 Runtime Connection Failover 不能使用 TAF,只能用 FCF。并且要做如下几件事情后才可以正常使用 FCF:1、把 implicit connection cache 打开;2、把 FastConnectionFailoverEnabled 打开;3、最好是直接订阅远程的 ONS(在Oracle 10gR2 之前的版本不能直接订阅远程的 ONS,只能通过在本地安装 ONS 后来实现 FAN events 的中转);4、最好是在 Java 程序里设置一下 TCP timeout(后面专门会讲到在 Oracle 数据库里如何调整 TCP timeout);
演示代码如下:
OracleDataSource ods = new OracleDataSource() ... ods.setUser(“Scott”)ods.setPassword(“tiger”)ods.setConnectionCachingEnabled(true); ods.setFastConnectionFailoverEnabled(true); ods.setConnectionCacheName(“MyCache”)ods.setConnectionCacheProperties(cp); ods.setONSConfiguration("nodes=racnode1:6201,racnode2.:6201"); ods.setURL("jdbc:oracle:thin:@sales1-scan:1521/oltp");//TCP connect timeoutProperties prop = new Properties();prop.setProperty("MinLimit", MIN_CONN);prop.setProperty("MaxLimit", MAX_CONN);prop.setProperty("InitialLimit", INIT_CONN);prop.put (oracle.net.ns.SQLnetDef.TCP_CONNTIMEOUT_STR, "1000")); // 这里是表示把TCP timeout设为1000毫秒,即1秒ods.setConnectionCacheProperties(prop);
例二:ODP.NET Fast Connection Failover (FCF)对于 ODP.NET 而言,通常做了如下几件事情后就可以使用 FCF 了:1、把对应 service 的 AQ Notification 打开:srvctl modify service -d RAC11g -s Email -q TRUE2、把 aq_tm_processes 的值设为 1;3、赋予指定用户 de-queue 的权限:exec dbms_aqadm.grant_queue_privilege(‘DEQUEUE‘,‘SYS.SYS$SERVICE_METRICS‘, <your username=>);4、在 .NET 连接串里设置 HA events=true;
演示代码如下:
// C# using System; using Oracle.DataAccess.Client; class ConnectionPoolingSample { static void Main() { OracleConnection con = new OracleConnection(); //Open a connection using ConnectionString attributes //related to connection pooling. con.ConnectionString = "User Id=scott;Password=tiger;Data Source=crm;" + "Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;" + "HA events=true", "Incr Pool Size=5; Decr Pool Si=2"; con.Open(); Console.WriteLine("Connection pool successfully created"); // Close and Dispose OracleConnection object con.Close(); con.Dispose(); Console.WriteLine("Connection is placed back into the pool."); } }
FCF 跟 TAF 有一个很大的不同就是即便是单纯 select 操作,FCF 也不能像 TAF 那样做到“断点续传”。对于配置好了 FCF 的连接池而言,当它接收到包含 instance/service 宕掉的 FAN HA events 后,原先 cache 在连接池里的跟这个 instance/service 相关的连接马上会被标记为失效(invalid)同时这些连接会被清除,使用这些连接的 transaction 也会马上中止并回滚。当应用捕捉到这个中止的 transaction 所产生的错误信息后,要么直接把相关错误返回给最终用户,要么从连接池中重新取得一个有效连接并重新执行这个被中止的 transaction。
在启用了 FCF 的情况下,如果连接错误被返回给了最终用户,那么应该如何判断错误信息的来源呢(即是否是 FCF 返回的错误)?很简单,用 isFatalConnectionError(SQLException e)来判断一下就好了,演示代码如下:
try { conn = getConnection(); //这里取得连接后做相关的工作} catch (SQLException e) { handleSQLException(e) } ... void handleSQLException (SQLException e) { if (OracleConnectionCacheManager.isFatalConnectionError(e)) ConnRetry = true; //这里表示捕捉到FCF返回的错误 …}
Oracle RAC 环境下的连接管理
标签:enabled 分享 guard 连接错误 消息 rri 顺序 roc res
小编还为您整理了以下内容,可能对您也有帮助:
需要了解Oracle RAC 的配置。
如何连接oracle数据库及故障解决办法
如何配置才能使客户端连到数据库:
要使一个客户端机器能连接oracle数据库,需要在客户端机器上安装oracle的客户端软件,唯一的例外就是java连接数据库的时候,可以用jdbc thin模式,不用装oracle的客户端软件。加入你在机器上装了oracle数据库,就不需要在单独在该机器上安装oracle客户端了,因为装oracle数据库的时候会自动安装oracle客户端。
用过sql server数据库然后又用oracle的新手可能会有这样的疑问:问什么我用sql server的时候不用装sql server的客户端呢?原因很简单,sql server也是microsoft的,它在操作系统中集成了sql server客户端,如果microsoft与oracle有协议,将oracle客户端也集成到操作系统中,那我们也就不用在客户端机器装oracle客户端软机就可访问数据库了,不过,这好像是不可能实现的事情。
也有的人会问:为什么在sql server中没有侦听端口一说,而在oracle中要配置侦听端口?其实sql server中也有侦听端口,只不过microsoft将侦听端口固定为1433,不允许你随便改动,这样给你一个错觉感觉sql server中没有侦听端口,咳,microsoft把太多的东西都封装到黑盒子里,方便使用的同时也带来的需要副作用。而oracle中的侦听端口直接在配置文件中,允许随便改动,只不过无论怎样改动,要与oracle服务器端设置的侦听端口一致。
好,言归正传,我们如何做才能使客户端机器连接到oracle数据库呢?
A. 安装相关软件
B. 进行适当的配置
A.在适当的位置安装适当的软件:
在客户端机器:
1.在客户端机器上安装ORACLE的Oracle Net通讯软件,它包含在oracle的客户端软件中。
2.正确配置了sqlnet.ora文件:
NAMES.DIRECTORY_PATH = (TNSNAMES, ….)
NAMES.DEFAULT_DOMAIN=DB_DOMAIN
一般情况下我们不用NAMES.DEFAULT_DOMAIN参数。如果想不用该参数用#注释掉或将该参数删除即可,对于NAMES.DIRECTORY_PATH参数采用缺省值即可,对于NAMES.DEFAULT_DOMAIN参数有时需要注释掉,在下面有详细解释。
3.正确配置了tnsname.ora文件
在服务器端机器:
1.保证listener已经启动
2.保证数据库已经启动。
如果数据库没有启动,用:
Oracle 9i:
dos>sqlplus “/ as sysdba”
sqlplus> startup
Oracle 8i:
dos>svrmgrl
svrmgrl>connect internal
svrmgrl>startup
命令启动数据库
如果listener没有启动,用:
lsnrctl start [listener name]
lsnrctl status [listener name]
命令启动listener
B.进行适当的配置
如何正确配置tnsname.ora文件:
可以在客户端机器上使用oracle Net Configuration Assistant或oracle Net Manager图形配置工具对客户端进行配置,该配置工具实际上修改tnsnames.ora文件。所以我们可以直接修改tnsnames.ora文件,下面以直接修改tnsnames.ora文件为例:
该文件的位置为: …\network\admin\tnsnames.ora (for windows)
…/network/admin/tnsnames.ora (for unix)
此处,假设服务器名为testserver,服务名为orcl.testserver.com,使用的侦听端口为1521,则tnsnams.ora文件中的一个test网络服务名(数据库别名)为:
test =
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)
)
)
此处的笑脸为)。
红色的内容为需要根据实际情况修改的内容,现解释如下:
PROTOCOL:客户端与服务器端通讯的协议,一般为TCP,该内容一般不用改。
HOST:数据库侦听所在的机器的机器名或IP地址,数据库侦听一般与数据库在同一个机器上,所以当我说数据库侦听所在的机器一般也是指数据库所在的机器。在UNIX或WINDOWS下,可以通过在数据库侦听所在的机器的命令提示符下使用hostname命令得到机器名,或通过ipconfig(for WINDOWS) or ifconfig(for UNIX)命令得到IP地址。需要注意的是,不管用机器名或IP地址,在客户端一定要用ping命令ping通数据库侦听所在的机器的机器名,否则需要在hosts文件中加入数据库侦听所在的机器的机器名的解析。
PORT:数据库侦听正在侦听的端口,可以察看服务器端的listener.ora文件或在数据库侦听所在的机器的命令提示符下通过lnsrctl status [listener name]命令察看。此处Port的值一定要与数据库侦听正在侦听的端口一样。
SERVICE_NAME:在服务器端,用system用户登陆后,sqlplus> show parameter service_name命令察看。
如何利用配置的网络服务名连接到数据库:
用sqlplus程序通过test网络服务名进行测试,如sqlplus system/manager@test。如果不能连接到数据库,则在tnsname.ora文件中的test网络服务名(net service)后面加上sqlnet.ora文件中NAMES.DEFAULT_DOMAIN参数的值,此处我的参数值为testserver.com,将其加到网络服务名后面,修改后的tnsname.ora中关于该网络服务名的内容为:
什么情况下会引起oracle自动设置NAMES.DEFAULT_DOMAIN参数?
出现这种情况的典型环境为windows的客户端的‘我得电脑à属性à计算机名à更改à其它…à此计算机的主DNS后缀’中设置了‘primary dns suffix’,因为在这种情况下安装客户端时,会在sqlnet.ora文件中自动设置NAMES.DEFAULT_DOMAIN参数,或许当把计算机加入域中安装oracle客户端时也会出现这种情况,有条件的话大家可以试一下。
我在设置oracle的客户端时一般手工修改tnsnames.ora文件,但是还有许多人喜欢用图形工具配置,该图形工具最终还是修改tnsnames.ora文件,但是它有时会引起其它的问题:
在用oracle的图形配置软件'net assistant'或‘Net Configuration Assistant’配置网络服务名时,假如已经设置了‘primary dns suffix’,但是在图形配置软件中写的网络服务名的名字中没有‘primary dns suffix’,如只是写了test,则图形配置软件会自动在后面加上‘primary dns suffix’,使之变为test.testserver.com,并存在tnsnames.ora中,而不管你的sqlnet.ora文件中是否有NAMES.DEFAULT_DOMAIN参数。此时,用图形工具进行测试连接是通过的,但是假如此时sqlnet.ora文件中没有NAMES.DEFAULT_DOMAIN参数,则你在使用网络服务名时应该使用在tnsnames.ora中的test.testserver.com,而不是你在图形配置软件中键入的test。解决的办法为:
<1>可以在sqlnet.ora文件中设置NAMES.DEFAULT_DOMAIN= testserver.com,这时你可以用test或test.testserver.com连接数据库
<2>在sqlnet.ora文件中不设置NAMES.DEFAULT_DOMAIN参数,在tnsnames.ora文件中将test.testserver.com中的.testserver.com去掉,这时你可以用test连接数据库。
关于为什们在网络服务名后面加db_domain参数,需要了解sql*plus连接数据库的原理,我在后面解决12154常见故障中给出了详细的说明。
如果上面的招数还不奏效的话,只好用一下乾坤大挪移了。
将客户端的网络服务名部分
test.testserver.com =
(DESCRIPTION=
(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)
)
)
此处的笑脸为)。
拷贝到服务器的tnsnames.ora文件中。然后再服务器端用sqlplus system/manager@test.testserver.com连接到数据库。
如果能连接成功,说明你的客户端与服务器端的网络有问题。
如果连接不成功,用前面的部分检查网络服务名部分部分是否正确,如果确信网络服务名部分正确而且所有的客户端都连不上数据库则可能为系统TCP/IP或Oracle系统有问题,建议重新安装数据库。
常见故障解决办法:
TNS-12154 (ORA-12154):TNS:could not resolve service name
该错误表示用于连接的网络服务名在tnsnames.ora文件中不存在,如上面的tnsnames.ora中的网络服务名只有test,假如用户在连接时用sqlplus system/manager@test1则就会给出TNS-12154错误。
要注意的是,有时即使在tnsnames.ora文件中有相应的网络服务名,可是用该网络服务名连接时还会出错,出现这种情况的典型配置如下(在客户端的机器上):
sqlnet.ora文件:
NAMES.DIRECTORY_PATH = (TNSNAMES, ….)
NAMES.DEFAULT_DOMAIN = server.com
tnsnames.ora文件:
test =
(DESCRIPTION=
(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)
)
)
此处的笑脸为)。
sql*plus运行基本机理:
在用户输入sqlplus system/manager@test后,sqlplus程序会自动到sqlnet.ora文件中找NAMES.DEFAULT_DOMAIN参数,假如该参数存在,则将该参数中的值取出,加到网络服务名的后面,即此例中你的输入由sqlplus system/manager@test自动变为sqlplus system/manager@test.server.com ,然后再到tnsnames.ora文件中找test.server.com网络服务名,这当然找不到了,因为该文件中只有test网络服务名,所以报错。解决的办法就是将sqlnet.ora文件中的NAMES.DEFAULT_DOMAIN参数注释掉即可,如#NAMES.DEFAULT_DOMAIN = server.com。假如NAMES.DEFAULT_DOMAIN参数不存在,则sqlplus程序会直接到tnsnames.ora文件中找test网络服务名,然后取出其中的host,port,tcp,service_name,利用这些信息将连接请求发送到正确的数据库服务器上。
另外原则上tnsnames.ora中的配置不区分大小写,但是我的确遇到区分大小写的情况,所以最好将使用的网络服务与tnsnames.ora中配置的完全一样。
ORA-12514: TNS:listener could not resolve SERVICE_NAME given in connect Descriptor.
该错误表示能在tnsnames.ora中找到网络服务名,但是在tnsnames.ora中指定的SERVICE_NAME与服务器端的SERVICE_NAME不一致。解决的办法是修改tnsnames.ora中的SERVICE_NAME。
易混淆术语介绍:
Db_name:对一个数据库(Oracle database)的唯一标识,该数据库为第一章讲到的Oracle database。这种表示对于单个数据库是足够的,但是随着由多个数据库构成的分布式数据库的普及,这种命令数据库的方法给数据库的管理造成一定的负担,因为各个数据库的名字可能一样,造成管理上的混乱。为了解决这种情况,引入了Db_domain参数,这样在数据库的标识是由Db_name和Db_domain两个参数共同决定的,避免了因为数据库重名而造成管理上的混乱。这类似于互连网上的机器名的管理。我们将Db_name和Db_domain两个参数用’.’连接起来,表示一个数据库,并将该数据库的名称称为Global_name,即它扩展了Db_name。Db_name参数只能由字母、数字、’_’、’#’、’$’组成,而且最多8个字符。
Db_domain:定义一个数据库所在的域,该域的命名同互联网的’域’没有任何关系,只是数据库管理员为了更好的管理分布式数据库而根据实际情况决定的。当然为了管理方便,可以将其等于互联网的域。
Global_name:对一个数据库(Oracle database)的唯一标识,oracle建议用此种方法命令数据库。该值是在创建数据库是决定的,缺省值为Db_name. Db_domain。在以后对参数文件中Db_name与Db_domain参数的任何修改不影响Global_name的值,如果要修改Global_name,只能用ALTER DATABASE RENAME GLOBAL_NAME TO <db_name.db_domain>命令进行修改,然后修改相应参数。
Service_name:该参数是oracle8i新引进的。在8i以前,我们用SID来表示标识数据库的一个实例,但是在Oracle的并行环境中,一个数据库对应多个实例,这样就需要多个网络服务名,设置繁琐。为了方便并行环境中的设置,引进了Service_name参数,该参数对应一个数据库,而不是一个实例,而且该参数有许多其它的好处。该参数的缺省值为Db_name. Db_domain,即等于Global_name。一个数据库可以对应多个Service_name,以便实现更灵活的配置。该参数与SID没有直接关系,即不必Service name 必须与SID一样。
Net service name:网络服务名,又可以称为数据库别名(database alias)。是客户端程序访问数据库时所需要,屏蔽了客户端如何连接到服务器端的细节,实现了数据库的位置透明的特性。
需要了解Oracle RAC 的配置。
如何连接oracle数据库及故障解决办法
如何配置才能使客户端连到数据库:
要使一个客户端机器能连接oracle数据库,需要在客户端机器上安装oracle的客户端软件,唯一的例外就是java连接数据库的时候,可以用jdbc thin模式,不用装oracle的客户端软件。加入你在机器上装了oracle数据库,就不需要在单独在该机器上安装oracle客户端了,因为装oracle数据库的时候会自动安装oracle客户端。
用过sql server数据库然后又用oracle的新手可能会有这样的疑问:问什么我用sql server的时候不用装sql server的客户端呢?原因很简单,sql server也是microsoft的,它在操作系统中集成了sql server客户端,如果microsoft与oracle有协议,将oracle客户端也集成到操作系统中,那我们也就不用在客户端机器装oracle客户端软机就可访问数据库了,不过,这好像是不可能实现的事情。
也有的人会问:为什么在sql server中没有侦听端口一说,而在oracle中要配置侦听端口?其实sql server中也有侦听端口,只不过microsoft将侦听端口固定为1433,不允许你随便改动,这样给你一个错觉感觉sql server中没有侦听端口,咳,microsoft把太多的东西都封装到黑盒子里,方便使用的同时也带来的需要副作用。而oracle中的侦听端口直接在配置文件中,允许随便改动,只不过无论怎样改动,要与oracle服务器端设置的侦听端口一致。
好,言归正传,我们如何做才能使客户端机器连接到oracle数据库呢?
A. 安装相关软件
B. 进行适当的配置
A.在适当的位置安装适当的软件:
在客户端机器:
1.在客户端机器上安装ORACLE的Oracle Net通讯软件,它包含在oracle的客户端软件中。
2.正确配置了sqlnet.ora文件:
NAMES.DIRECTORY_PATH = (TNSNAMES, ….)
NAMES.DEFAULT_DOMAIN=DB_DOMAIN
一般情况下我们不用NAMES.DEFAULT_DOMAIN参数。如果想不用该参数用#注释掉或将该参数删除即可,对于NAMES.DIRECTORY_PATH参数采用缺省值即可,对于NAMES.DEFAULT_DOMAIN参数有时需要注释掉,在下面有详细解释。
3.正确配置了tnsname.ora文件
在服务器端机器:
1.保证listener已经启动
2.保证数据库已经启动。
如果数据库没有启动,用:
Oracle 9i:
dos>sqlplus “/ as sysdba”
sqlplus> startup
Oracle 8i:
dos>svrmgrl
svrmgrl>connect internal
svrmgrl>startup
命令启动数据库
如果listener没有启动,用:
lsnrctl start [listener name]
lsnrctl status [listener name]
命令启动listener
B.进行适当的配置
如何正确配置tnsname.ora文件:
可以在客户端机器上使用oracle Net Configuration Assistant或oracle Net Manager图形配置工具对客户端进行配置,该配置工具实际上修改tnsnames.ora文件。所以我们可以直接修改tnsnames.ora文件,下面以直接修改tnsnames.ora文件为例:
该文件的位置为: …\network\admin\tnsnames.ora (for windows)
…/network/admin/tnsnames.ora (for unix)
此处,假设服务器名为testserver,服务名为orcl.testserver.com,使用的侦听端口为1521,则tnsnams.ora文件中的一个test网络服务名(数据库别名)为:
test =
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)
)
)
此处的笑脸为)。
红色的内容为需要根据实际情况修改的内容,现解释如下:
PROTOCOL:客户端与服务器端通讯的协议,一般为TCP,该内容一般不用改。
HOST:数据库侦听所在的机器的机器名或IP地址,数据库侦听一般与数据库在同一个机器上,所以当我说数据库侦听所在的机器一般也是指数据库所在的机器。在UNIX或WINDOWS下,可以通过在数据库侦听所在的机器的命令提示符下使用hostname命令得到机器名,或通过ipconfig(for WINDOWS) or ifconfig(for UNIX)命令得到IP地址。需要注意的是,不管用机器名或IP地址,在客户端一定要用ping命令ping通数据库侦听所在的机器的机器名,否则需要在hosts文件中加入数据库侦听所在的机器的机器名的解析。
PORT:数据库侦听正在侦听的端口,可以察看服务器端的listener.ora文件或在数据库侦听所在的机器的命令提示符下通过lnsrctl status [listener name]命令察看。此处Port的值一定要与数据库侦听正在侦听的端口一样。
SERVICE_NAME:在服务器端,用system用户登陆后,sqlplus> show parameter service_name命令察看。
如何利用配置的网络服务名连接到数据库:
用sqlplus程序通过test网络服务名进行测试,如sqlplus system/manager@test。如果不能连接到数据库,则在tnsname.ora文件中的test网络服务名(net service)后面加上sqlnet.ora文件中NAMES.DEFAULT_DOMAIN参数的值,此处我的参数值为testserver.com,将其加到网络服务名后面,修改后的tnsname.ora中关于该网络服务名的内容为:
什么情况下会引起oracle自动设置NAMES.DEFAULT_DOMAIN参数?
出现这种情况的典型环境为windows的客户端的‘我得电脑à属性à计算机名à更改à其它…à此计算机的主DNS后缀’中设置了‘primary dns suffix’,因为在这种情况下安装客户端时,会在sqlnet.ora文件中自动设置NAMES.DEFAULT_DOMAIN参数,或许当把计算机加入域中安装oracle客户端时也会出现这种情况,有条件的话大家可以试一下。
我在设置oracle的客户端时一般手工修改tnsnames.ora文件,但是还有许多人喜欢用图形工具配置,该图形工具最终还是修改tnsnames.ora文件,但是它有时会引起其它的问题:
在用oracle的图形配置软件'net assistant'或‘Net Configuration Assistant’配置网络服务名时,假如已经设置了‘primary dns suffix’,但是在图形配置软件中写的网络服务名的名字中没有‘primary dns suffix’,如只是写了test,则图形配置软件会自动在后面加上‘primary dns suffix’,使之变为test.testserver.com,并存在tnsnames.ora中,而不管你的sqlnet.ora文件中是否有NAMES.DEFAULT_DOMAIN参数。此时,用图形工具进行测试连接是通过的,但是假如此时sqlnet.ora文件中没有NAMES.DEFAULT_DOMAIN参数,则你在使用网络服务名时应该使用在tnsnames.ora中的test.testserver.com,而不是你在图形配置软件中键入的test。解决的办法为:
<1>可以在sqlnet.ora文件中设置NAMES.DEFAULT_DOMAIN= testserver.com,这时你可以用test或test.testserver.com连接数据库
<2>在sqlnet.ora文件中不设置NAMES.DEFAULT_DOMAIN参数,在tnsnames.ora文件中将test.testserver.com中的.testserver.com去掉,这时你可以用test连接数据库。
关于为什们在网络服务名后面加db_domain参数,需要了解sql*plus连接数据库的原理,我在后面解决12154常见故障中给出了详细的说明。
如果上面的招数还不奏效的话,只好用一下乾坤大挪移了。
将客户端的网络服务名部分
test.testserver.com =
(DESCRIPTION=
(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)
)
)
此处的笑脸为)。
拷贝到服务器的tnsnames.ora文件中。然后再服务器端用sqlplus system/manager@test.testserver.com连接到数据库。
如果能连接成功,说明你的客户端与服务器端的网络有问题。
如果连接不成功,用前面的部分检查网络服务名部分部分是否正确,如果确信网络服务名部分正确而且所有的客户端都连不上数据库则可能为系统TCP/IP或Oracle系统有问题,建议重新安装数据库。
常见故障解决办法:
TNS-12154 (ORA-12154):TNS:could not resolve service name
该错误表示用于连接的网络服务名在tnsnames.ora文件中不存在,如上面的tnsnames.ora中的网络服务名只有test,假如用户在连接时用sqlplus system/manager@test1则就会给出TNS-12154错误。
要注意的是,有时即使在tnsnames.ora文件中有相应的网络服务名,可是用该网络服务名连接时还会出错,出现这种情况的典型配置如下(在客户端的机器上):
sqlnet.ora文件:
NAMES.DIRECTORY_PATH = (TNSNAMES, ….)
NAMES.DEFAULT_DOMAIN = server.com
tnsnames.ora文件:
test =
(DESCRIPTION=
(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)
)
)
此处的笑脸为)。
sql*plus运行基本机理:
在用户输入sqlplus system/manager@test后,sqlplus程序会自动到sqlnet.ora文件中找NAMES.DEFAULT_DOMAIN参数,假如该参数存在,则将该参数中的值取出,加到网络服务名的后面,即此例中你的输入由sqlplus system/manager@test自动变为sqlplus system/manager@test.server.com ,然后再到tnsnames.ora文件中找test.server.com网络服务名,这当然找不到了,因为该文件中只有test网络服务名,所以报错。解决的办法就是将sqlnet.ora文件中的NAMES.DEFAULT_DOMAIN参数注释掉即可,如#NAMES.DEFAULT_DOMAIN = server.com。假如NAMES.DEFAULT_DOMAIN参数不存在,则sqlplus程序会直接到tnsnames.ora文件中找test网络服务名,然后取出其中的host,port,tcp,service_name,利用这些信息将连接请求发送到正确的数据库服务器上。
另外原则上tnsnames.ora中的配置不区分大小写,但是我的确遇到区分大小写的情况,所以最好将使用的网络服务与tnsnames.ora中配置的完全一样。
ORA-12514: TNS:listener could not resolve SERVICE_NAME given in connect Descriptor.
该错误表示能在tnsnames.ora中找到网络服务名,但是在tnsnames.ora中指定的SERVICE_NAME与服务器端的SERVICE_NAME不一致。解决的办法是修改tnsnames.ora中的SERVICE_NAME。
易混淆术语介绍:
Db_name:对一个数据库(Oracle database)的唯一标识,该数据库为第一章讲到的Oracle database。这种表示对于单个数据库是足够的,但是随着由多个数据库构成的分布式数据库的普及,这种命令数据库的方法给数据库的管理造成一定的负担,因为各个数据库的名字可能一样,造成管理上的混乱。为了解决这种情况,引入了Db_domain参数,这样在数据库的标识是由Db_name和Db_domain两个参数共同决定的,避免了因为数据库重名而造成管理上的混乱。这类似于互连网上的机器名的管理。我们将Db_name和Db_domain两个参数用’.’连接起来,表示一个数据库,并将该数据库的名称称为Global_name,即它扩展了Db_name。Db_name参数只能由字母、数字、’_’、’#’、’$’组成,而且最多8个字符。
Db_domain:定义一个数据库所在的域,该域的命名同互联网的’域’没有任何关系,只是数据库管理员为了更好的管理分布式数据库而根据实际情况决定的。当然为了管理方便,可以将其等于互联网的域。
Global_name:对一个数据库(Oracle database)的唯一标识,oracle建议用此种方法命令数据库。该值是在创建数据库是决定的,缺省值为Db_name. Db_domain。在以后对参数文件中Db_name与Db_domain参数的任何修改不影响Global_name的值,如果要修改Global_name,只能用ALTER DATABASE RENAME GLOBAL_NAME TO <db_name.db_domain>命令进行修改,然后修改相应参数。
Service_name:该参数是oracle8i新引进的。在8i以前,我们用SID来表示标识数据库的一个实例,但是在Oracle的并行环境中,一个数据库对应多个实例,这样就需要多个网络服务名,设置繁琐。为了方便并行环境中的设置,引进了Service_name参数,该参数对应一个数据库,而不是一个实例,而且该参数有许多其它的好处。该参数的缺省值为Db_name. Db_domain,即等于Global_name。一个数据库可以对应多个Service_name,以便实现更灵活的配置。该参数与SID没有直接关系,即不必Service name 必须与SID一样。
Net service name:网络服务名,又可以称为数据库别名(database alias)。是客户端程序访问数据库时所需要,屏蔽了客户端如何连接到服务器端的细节,实现了数据库的位置透明的特性。
oracle rac问题
rac不是分布式数据库,rac结构无论多少个实例都是一个数据库,事务间不需要协调,而所谓的分布式数据库是多个数据库协同工作,事务间需要协调机制。
1、数据库中建立的表是在机器1还是在机器2呢?
答:机器1和机器上2看到的数据库实际上是同一个数据库,所以表既可以在机器1上看到也可以在机器2上看到。
2、如果有个表,在做机器1停机维护时(此时机器2仍可供访问),对这个机器上的表做索引重建,那么是否会影响机器2的使用?
答:如果机器1上的实例对表重建索引,其效果等于机器2上的实例对表重建索引,所以会影响机器2对该表的使用。例如你在机器1上重建索引时没有加上online关键字,重建过程中机器2不能对该表进行dml。
补充:
机器1和机器2看到的库实际上是同一个库,所以在机器1上给某表重建索引时对该表加的锁,也会影响机器2对该表的使用。就像我前面说的,假如你在机器1上重建索引时没有加上online关键字,重建过程中机器2不能对该表进行dml。再进一步说明,你在机器1上重建索引的过程中,机器2也不能将这个表drop掉,原因就是机器1在这个表上加上了ddl锁。
oracle rac是什么
RAC (Real Application Clusters)是 Oracle 数据库的一个群集解决方案,是有着两个或者两个以上的数据库节点协调运作能力的。
单节点数据库,如果实例宕机了,如果一个业务、在实例上面,那么这个业务就中断了。这个时候系统就不具有可用性了,那么这个时候单节点的可用性是很差的。
于RAC来说,和单实例一样,还是一份数据文件,都是相同的存储上面放着oracle的文件,但是是由三个实例共用同一份数据文件。这样的好处是在三个实例之间做了冗余,在上面三个实例当中任意两个坏了业务都可以连剩下的一个实例,都可以正常的工作。RAC提供了在实例级别的冗余。
一般每个实例都放在不同的服务器上面,这样可以起到冗余作用。所有的数据库文件都放在共享存储上面,但是还有一些文件放在每个实例自己的本地的磁盘上面,比如参数文件,每一个实例都可以有自己的参数文件,这个参数文件既可以放在本地也可以放在共享存储上面,多个实例都使用同一个参数文件。
RAC不能够解决在数据的安全,尽管有多个实例,但是只有一份数据文件,这样只要数据文件损坏了,那么整个数据库就损坏了。