实验环境
搭建平台:VMware Workstation
OS:RHEL 7.6
Grid&DB:Oracle 12.2.0.1
问题描述
1. 网卡NIC发生故障后,发现数据库注册不到本地监听器(监听使用的VIP):
$ lsnrctl status ##此处省略一部分输出## Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.xx.xx.165)(PORT=1521))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.xx.xx.166)(PORT=1521))) The listener supports no services ##没有服务被注册
2. 手工强制注册监听:
SQL> alter system register;
再次检查发现任然没有注册上
3. 检查listener相关参数:
SQL> show parameter listener NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ listener_networks string local_listener string (ADDRESS=(PROTOCOL=TCP)(HOST= 192.xx.xx.166)(PORT=1521)) remote_listener string testdb-scan:1521
貌似也没有什么问题......
4. 检查trace日志跟踪显示发送了正确的注册信息,但是监听器似乎从未接收过服务信息。
$ vim /oracle/app/oracle/diag/rdbms/testdb/testdb1/trace/testdb1_lreg_3891.trc ##此处省略一部分输出## Unix process pid: 3891, image: oracle@racdb01 (LREG) ##此处省略一部分输出## Local listeners: 0 - (ADDRESS=(PROTOCOL=TCP)(HOST=192.xx.xx.166)(PORT=1521)) pdb 1 dci 0 state=2, err=0 nse[0]=0, nse[1]=0, nte[0]=0, nte[1]=0, nte[2]=0 ncre=0 endp=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.xx.xx.166)(PORT=1521))) flg=0x80000000 nse=0 pri=0x101815c75
日志显示注册信息已经发送出去了,但是监听却收到过服务信息。
5. 检查scan的监听:
$ lsnrctl status listener_scan1
发现scan没问题,能看见服务注册上去。
6. 最后再检查VNCR(Valid Node Checking Registration)设置:
$ lsnrctl show valid_node_checking_registration LSNRCTL for LINUX RISC System/6000: Version 12.2.0.1.0 - Production on 16-AUG-2021 10:25:57 Copyright (c) 1991, 2016, Oracle. All rights reserved. Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER))) LISTENER parameter "valid_node_checking_registration" set to SUBNET ##这里显示被设置为SUBNET(一般默认就是这个值)
解决办法
咨询了Oracle官方人员,这是一个未公开的 Bug 26739452 引起的,后来我查该Bug编号也确实查不出来。
该Bug与 CRS 自动将 VNCR设置为 SUBNET 值有关,即使在单节点环境中也是如此在这种情况下:当一个节点关闭时,如果没有子网,数据库仍在尝试“SUBNET”安全设置,就会导致LOCAL注册出现问题。 这个Bug在Oracle 18c修复了。
所以,如果不想升级12c,那么解决办法如下:
将LOCAL_LISTENER设置为本地VIP监听器的IPC地址,不再用TCP地址:
SQL> alter system set LOCAL_LISTENER='(ADDRESS=(PROTOCOL=
IPC)(KEY=LISTENER))' scope=both sid='*';
SQL> alter system register;
注:
1)KEY的值要与 listener.ora 文件中的KEY的值相同
2) 用于 LOCAL 监听器注册的 IPC 地址实际上是首选,因为它更安全(IPC仅是“本地”协议),并且它更快(IPC 不容易发生 TCP 网络流量变化)
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69992972/viewspace-2789173/ ,如需转载,请注明出处,否则将追究法律责任。