日常问题诊断:11Gr2 RAC 监听问题(local_listener,listener_networks)

环境介绍:

11gr2 rac 双节点,两个network资源,network1作为应用访问,network2作为DG,OGG同步备份网络;对应的有两个本地监听LISTENER(端口1521),LISTENER_DG(1621),一个SCAN监听

 

昨晚趁着存储链路调整,修改了生产环境监听配置。

 

我们知道11Gr2 rac下,监听文件不再像原来在oracle用户下的$ORACLE_HOME/network/admin目录下了,而是变成了grid用户下的$ORACLE_HOME/network/admin目录下。因此监听的启停以及查看状态都是在grid用户下。

 

另外,11Gr2 对于监听文件,官方不推荐手动配置(vi),而是通过工具添加生成(srvctl)。我们之所以做监听变更也正是这个原因。一节点监听文件是正常工具生成的格式,二节点不是,从而导致查看集群信息时,二节点的监听状态一直是INTERMEDIATE,而且报错Not All Endpoints Registered。

 

一节点listener.ora:

LISTENER_DG=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_DG)))) # line added by Agent

LISTENER=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))) # line added by Agent

LISTENER_SCAN1=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN1)))) # line added by Agent

ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN1=ON # line added by Agent

ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER=ON # line added by Agent

ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_DG=ON # line added by Agent

 

二节点listener.ora:

ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN1 = ON

LISTENER_DG =

(DESCRIPTION_LIST =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = edw2-dg-vip)(PORT = 1621))

)

)

 

ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_DG = ON

LISTENER =

(DESCRIPTION_LIST =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = sfpay-edw-db02)(PORT = 1521))

)

)

 

ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER = ON

LISTENER_SCAN1 =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = IPC)(KEY = LISTENER_SCAN1))

)

)

 

因此我们将二节点的的listener.ora修改成和一节点一致。做完变更后,将监听起来,发现监听集群信息正常:

ora.LISTENER.lsnr

ONLINE ONLINE sfpay-edw-db01

ONLINE ONLINE sfpay-edw-db02

ora.LISTENER_DG.lsnr

ONLINE ONLINE sfpay-edw-db01

ONLINE ONLINE sfpay-edw-db02

ora.net1.network

ONLINE ONLINE sfpay-edw-db01

ONLINE ONLINE sfpay-edw-db02

ora.net2.network

ONLINE ONLINE sfpay-edw-db01

ONLINE ONLINE sfpay-edw-db02

ora.LISTENER_SCAN1.lsnr

1 ONLINE ONLINE sfpay-edw-db01

 

然而查看LISTENER_DG的状态时,数据库服务一直注册不上,所以导致通过这个监听访问的客户端一直访问不了:

grid>>lsnrctl status LISTENER_DG

.......

The listener supports no services

The command completed successfully

 

但是LISTENER,SCAN监听的服务却是正常的,并且数据库服务也能注册上。

grid>>lsnrctl status LISTENER

.....Services Summary...

Service "+ASM" has 1 instance(s).

Instance "+ASM1", status READY, has 1 handler(s) for this service...

Service "biolapdb" has 1 instance(s).

Instance "biolapdb1", status READY, has 1 handler(s) for this service...

Service "biolapdbXDB" has 1 instance(s).

Instance "biolapdb1", status READY, has 1 handler(s) for this service...

The command completed successfully

 

因为我们这里使用的是动态监听,于是想到可能PMON只是向LISTENER注册了服务,而没有将服务注册到LISTENER_DG。而控制这个行为的参数是local_listener。于是我们查看:

sqlplus>>show parameter local_listener

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

local_listener string

 

发现为空。于是查了下这个参数得解释:

local_listener这个参数得作用就是告诉pmon把注册信息注册到local_listener指定的地址上,默认不指定的话,value为空,则会动态注册本地ip 的1521端口,即等价于:

local_listener=' (ADDRESS = (PROTOCOL = TCP)(HOST = 本机ip)(PORT = 1521))'

而其他端口,oracle是没法知道的。

这就解释了为什么LISTENER正常,而LISTENER_DG不正常,因为LISTENER_DG是用的1621端口。

 

因此到这里问题就好解决了,在两个节点将这两个监听都加入到local_listener中就可以解决:

alter system set local_listener='(DESCRIPTION= (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=edw1-dg-vip)(PORT=1621)) (ADDRESS=(PROTOCOL=TCP)(HOST= sfpay-edw-db01)(PORT=1521))))' scope=both sid='biolapdb1';

 

alter system set local_listener='(DESCRIPTION= (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=edw2-dg-vip)(PORT=1621)) (ADDRESS=(PROTOCOL=TCP)(HOST= sfpay-edw-db02)(PORT=1521))))' scope=both sid='biolapdb2';

 

alter system register;

或者local_listener='LISTENER,LISTENER_DG',

这样的前提是在tnsname.ora里将具体信息添加进去。

 

此时在查看LISTENER_DG监听,状态正常,服务正常。

 

 

-----------------------------------------------------------------------------------

 

但是当我查看其相同架构的数据库参数时,发现:

SQL> show parameter listen

 

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

listener_networks string ((NAME=network1)(LOCAL_LISTENE

R=SYPDB2_LOCAL)(REMOTE_LISTENE

R=db.sypay.sfp.com:1521)), ((N

AME=network2)(LOCAL_LISTENER=S

YPDB2_LOCAL_DG)(REMOTE_LISTENE

R=SYPDB_REMOTE_DG))

local_listener string

remote_listener string db.sypay.sfp.com:1521

 

listener_networks参数有值,local_listener参数是保持的默认值,但是其库上的LISTENER_DG是正常的。

 

此时参考了一下博客:http://www.lunar2013.com/2016/02/oracle-12c-rac-%E9%85%8D%E7%BD%AE%E7%AC%AC%E4%BA%8C%E4%B8%AA%E7%BD%91%E7%BB%9C%E5%92%8C%E7%9B%B8%E5%BA%94%E7%9A%84scan2.html

 

发现其中有一步骤:配置ORACLE数据库实例支持多个网络

于是,继续修改:

oracle >>vim tnsnames.ora

EDWDB1_LOCAL =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = sfpay-edw1-vip)(PORT = 1521))

)

 

EDWDB2_LOCAL =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = sfpay-edw2-vip)(PORT = 1521))

)

 

EDWDB1_LOCAL_DG =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = edw1-dg-vip)(PORT = 1621))

)

 

 

EDWDB2_LOCAL_DG =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = edw2-dg-vip)(PORT = 1621))

)

 

EDWDB2_REMOTE_DG =

(DESCRIPTION_LIST =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = edw1-dg-vip)(PORT = 1621))

)

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = edw2-dg-vip)(PORT = 1621))

)

)

 

alter system set listener_networks='((NAME=network1)(LOCAL_LISTENER=EDWDB1_LOCAL)(REMOTE_LISTENER=db.edw.sfp.com:1521))','((NAME=network2)(LOCAL_LISTENER=EDWDB1_LOCAL_DG)(REMOTE_LISTENER=EDWDB2_REMOTE_DG))' scope=both sid='biolapdb1';

alter system set listener_networks='((NAME=network1)(LOCAL_LISTENER=EDWDB2_LOCAL)(REMOTE_LISTENER=db.edw.sfp.com:1521))','((NAME=network2)(LOCAL_LISTENER=EDWDB2_LOCAL_DG)(REMOTE_LISTENER=EDWDB2_REMOTE_DG))' scope=both sid='biolapdb2';

 

然后将local_listener置为空:

alter system set local_listener='' scope=both sid='biolapdb1';

alter system set local_listener='' scope=both sid='biolapdb2';

 

alter system set remote_listener ='' scope=both sid='biolapdb1';

alter system set remote_listener ='' scope=both sid='biolapdb2';

 

发现效果一样。

 

 

总结:出现这个问题的原因,其实最终归结于对监听器以及local_listener,remote_listener ,listener_networks这三个参数的不了解。

 

对于监听器,数据库将服务注册到监听器里。静态监听的话,服务都写在了listener.ora文件里,监听器启动的时候会自动将这些服务注册,而不管数据库服务的状态(即使数据库服务在close状态,客户端请求时,也能登录,只不过是idle状态);动态监听的话,listener.ora文件里没有具体的服务内容(SID_LIST_LISTENER),只有LISTENER内容,数据库在启动后,PMON进程会自动将数据库服务注册到该监听器上,不过PMON默认只注册到1521的监听器上,如果监听不是1521端口,此时就需要local_listener参数指定。或者当有多个动态监听时,想让PMON动态将服务注册到多个监听上时,则需要local_listener指定多个条目。

 

对于remote_listener,只当数据库服务和监听器不再同一台机器上时用到的。不过我们平时rac环境里更多的用处是在每个节点上将remote_listener指定为scan监听,这样scan监听就能监听每个节点的服务,从而能通过scan ip就能负载均衡的访问每个节点。(scan通过每个节点上的本地监听器来探测每个节点上的压力,从而将请求分发到合适的节点上,最终还是通过本地监听来访问数据库的)

 

对于listener_networks, 当有多个network网络,比如想给数据库添加专用的DG网络,减少因为备份传输引起的带宽资源不够。这样在DG网络上也会有自己的local_listener,以及remote_listener ,此时就可以使用listener_networks参数来指定值,该参数里包含了每个网络对应的name,local_listener,remote_listener 参数;所以当我们指定了listener_networks参数后,就无需指定

local_listener,remote_listener参数了。

你可能感兴趣的:(日常问题诊断)