Orlace 数据库连接的那些事儿:服务器端(三)

来源:互联网 发布:阿里云免费证书配置 编辑:程序博客网 时间:2024/06/13 05:12

RAC 中的 LOCAL_LISTENER


    最近有一个 10gR2 的安装案例。似乎一切都是按照规范设置的,但偶尔会在客户端上出现 ora-12545 错误、连接数据库失败。特别是在进行故障转移测试时,问题更加严重。

    经过努力解决了这些问题之后,我们认识到,RAC 的安装过程非常容易出现这些问题,也因此提示我应该就此写一篇博文。如果现在您正在做 RAC 安装,或是负责 RAC 数据库管理,应该马上敲一个 “show parameter LISTENER”命令,看一下输出结果,这对我们后面的分析会有帮助。

    再回到刚才提到的案例上。在查看了 sqlnet 客户端的跟踪信息之后,我们发现客户端的连接请求被重定向了服务器的主机名称,而不是 RAC 的虚地址。这有会两个问题:

    1、客户端不能将这个服务器的主机名称解析成 IP 地址,因为这个主机名即没在 DNS 服务器上,也没有出现在客户端的 hosts 文件中。

    2、无论如何,客户端都不应该按服务器的主机名称(而不是虚地址或虚主机名)请求连接。

    客户端的 tnsnames.ora 文件以及服务器端的 tnsnames.ora 文件和 listener.ora 文件都已经检查过了,所有这些文件中都设置成了 RAC 的虚地址,那么跟踪信息中提到的“物理的”主机名称又是从哪里来的呢?答案是:来自于服务器端的 LOCAL_LISTENER 参数。 

    那么你可能会问,是不是只要客户端的连接描述符(取自 tnsnames.ora 文件)使用虚地址就能保证安全地连接到数据库了?实际上并不是这样,其中原委,只有在深入理解了监听程序的工作机制之后,才能理解。

     问题源自于 10g  实例向监听程序注册时所用的方法。如果没有对平台相关的集群安装指引文档的第九节《Understanding the Oracle Real Application Clusters Installed Configuration》给予特别关注的话,很容易被这个问题所困扰。

    如果使用的是 DEDICATED 服务器配置的话,LOCAL_LISTENER 被用于实例到监听的注册。如果你使用端口 1521 上的默认监听,那么 DBCA 就不会设置 LOCAL_LISTENER 的值。文档的第 9.8 节《Configuring the Listener File (listener.ora)》讲了如何手工设置 LOCAL_LISTENER 的正确值。但如果没有手工设置的话,其默认值就采用了物理的主机地址(而不是虚地址)

    你可能会认为,连接到物理主机地址也没错啊?确实是这样,但这存在两个问题:

    1、如果这个地址在 DNS 中不存在,客户端就不能解析这个主机地址。更严重的是

    2、如果 RAC 进行了故障转移,客户端所实际连接的服务器不会随着虚拟 IP 地址位置的变化而改变。

    即使有这些问题,你可能还会认为这个问题很少出现,因为客户端的 tnsnames 以及其他的使用网络名称的位置都是要求连接到虚地址的。

   这个问题的答案也是否定的。由于 RAC 的负载管理和监听重定向的原因,即使 tnsnames 告诉客户端连接到虚地址,客户端还是会连接到物理的主机地址,这是很常见的现象。

    我们来看一个 RAC 的例子,集群的名字叫 SVC,两个实例,分别是 SVC1 和 SVC2,运行于主机 host1 和 host2 上 (其虚地址分别是 host1_vip 和 host2_vip)。客户端的 tnsnames 是这样的:

SVC =
    (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = host1_vip)(PORT = 1521))
        (ADDRESS = (PROTOCOL = TCP)(HOST = host2_vip)(PORT = 1521))
            (LOAD_BALANCE = yes)
            (CONNECT_DATA =
                (SERVER = DEDICATED)
                (SERVICE_NAME = SVC)
                (FAILOVER_MODE=(TYPE=select)
                (METHOD=basic)
                (RETRIES=10)
                (DELAY=1))
        )
    )



    上图说明的是,当 LOCAL_LISTENER 参数未设置为正确值时,监听程序处理连接请求的过程。其处理流程如下:

    1、客户端从 tnsnames 的地址地址列表中选取一个虚地址对应的主机名称,并用此地址尝试连接数据库。此例中,选的是 host1_vip 上的监听。

    2、监听程序将选择一个最适合的实例来为这个对 SVC 服务的请求建立一个会话。此时如果本地实例 SVC1 是宕掉的,或者监听程序认为实例 SVC2更适合为这个请求提供服务,它会给客户端发送一个监听重定向命令,而这个重定向命令中的地址就是物理主机名(host2),而不是虚拟主机名(host2_vip)。(译注:这就是为什么客户端的跟踪会发现有物理主机名称的原因。)

    3、如果客户端不能解析 host2,就会返回 ORA_12545 错误。如果能够正确解析这个地址,那么,客户端就能与 host2 的监听上建立连接。如果实例 SVC2 正处于运行状态,则数据库连接就可以成功的建立起来。但是,如果 host2 宕掉了,会发生什么情况呢?CRS 肯定会将 host2_vip 漂移到 host1 上,但是客户端在重定向后却是请求 连接到 地址 host2 上的,这时就会出现 TCP 超时错误。也许,客户端最终会获知连接不可到达,然后再一次尝试与数据库建立连接(使用 VIP),但这时应用程序可能已经等待了很长时间了(具体时间长短,要看 TCP 和 sqlnet 的参数设置)。

   

    现在我们来看一下,当正确设置了 LOCAL_LISTENER 的值时,会发生什么情况(如上图):

    1、客户端从 tnsnames 的地址列表中选择一个虚地址(主机名称)尝试连接,此例中,所选为 host1_vip 上的监听。

    2、监听程序会选择一个最适合的实例来为 SVC 的服务请求建立一个会话。如果本地的 SVC1 实例当掉了,或者它认为 SVC2 能够更好的服务于连接请求,它就会给客户端发送一个重定向命令。这个重定向命令中给出的地址是虚拟主机地址(host2_vip)。

    3、这样一个到 host2_vip 地址上 SVC2 实例的连接就成功建立起来了。但是,我们还应该探讨一下如果 host2 宕掉了,会发生什么情况。

    4、这时 CRS 一定会将 host2_vip 这个虚地址漂移到 host1 上,客户端连接也会跟着这个 VIP 发送到 host1 上。但两者之间的通讯会有一个短暂的中断(中断时间长短,和 VIP 漂移所需要的时间有关,也和其他因素有关,如在使用 NAT 路由器时,地址转换表的更新也需要时间)。在很短时间内,数据库连接就可以恢复,应用可能可以继续原来的工作,具体情况要依 FAILOVER_MODE 参数的设置(session、select)而定。

 

    幸运的是,这个问题很容易修复。只要修改 LOCAL_LISTENER 参数,使其指向虚地址就可以了。

    关于解决此问题以及如何设置与此问题相关的 LOCAL_LISTENER 参数,Oracle 发布了几个 metalink note (342419.1, 333159.1)。但是,在着手写此博文(并试图解决此问题)时,发现 note 342419.1 对解决方法的描述并不完全正确。 

    此篇 note 中提到,使用如下命令设置 LOCAL_LISTENER 参数 (服务器上的 tnsnames.ora 有一个名字为 LISTENER_LXDB0036 的实例连接串,它使用的是虚地址)。

    Alter system set LOCAL_LISTENER= 'LISTENER_LXDB0036' scope=both;

    显然,此命令把所有实例的的 LOCAL_LISTENER 都修改了。对此错误,有两种解决方法可供选择:

    1、修改每台服务器上 tnsmanes.ora 文件,使每台服务器上的 LISTENER_LXDB0036 定义都指向特定的实例。

    2、我认为最好的解决方法:在 alter system 命令的添加一个 SID 参数,使之指向特定的实例。

Alter system set LOCAL_LISTENER= 'LISTENER_LXDB0036' scope=both SID='SVC1';

 

     应该注意的是,这个监听注册问题,只有在创建数据库时监听使用了默认端口才会出现。很显然,如果使用 DBCA 创建数据库时使用了非默认的监听设置,LOCAL_LISTENER 参数会设置成正确值,指向一个 VIP,但我还未就此进行实验验证。

     文章结尾了,我再提示一下。如果你在安装、或负责管理 RAC,我强烈建议现在就敲一个 “show parameter LISTENER" 命令,以确保不会有潜在的 HA 问题出现。


    原文地址:http://blog.tardate.com/2007/06/check-locallistener-if-you-run-rac.html

0 0
原创粉丝点击