Listener使用ip导致dgbroker报ORA-12514
有一套adg环境,数据正常同步,同时也部署配置了dgbroker管理工具, 但是在运行一会后会出现TNS的报错,在做swithover和failover也会失败,根据alert日志可以发现做切换的时候会去访问db_unique_name_DGB的TNS,而查看主备起的监听,却并没有发现这样一个service,经过查资料,这个监听是会在dgbroker服务起来的时候动态注册的,动态注册的时候是去找的隐含参数__dg_broker_service_names
下面是一个正常的环境下的情况
1 | SQL> @pd dg_broker_service |
正常情况下已经启动的监听
1 | Service "ora12c" has 1 instance(s). |
而当停掉dgbroker服务以后,service也随之消失
1 | SQL> alter system set dg_broker_start = FALSE; |
而这个有问题的环境是采用的静态监听,却没有自动注册到DGB的service,最后的原因竟然是listener.ora里面配置的是IP地址,而不是hostname。
我们知道数据库的服务注册都是通过PMON进程来完成,PMON进程来尝试注册数据库的service。默认情况下,监听都是运行在1521端口,但是并不确定它要去连接的IP地址是哪一个。这种情况下PMON选择的地址与绑定监听的IP地址不同,这个地址由hosts配置来决定。
而由于我们的监听配置的是原始的IP地址,这样它就只会绑定和监听在这个IP地址上,从PMON发起的连接就会失败。
问题的解决办法如下:
将这个监听去绑定系统所有的地址,在listener.ora中配置hostname而不是固定的ip地址。监听会在所有地址上等待PMON的连接,只有这种方式PMON才能连接上监听
让PMON去注册指定的listener ip地址,这种情况下需要修改
local_listener
参数为指向listener的service name,或者一个完整的地址,这样PMON就会清楚的知道哪个IP地址和端口是被监听所允许连接的。1
2SQL> alter system set local_listener= LISTENER_TEST;
SQL> alter system set LOCAL_LISTENER='(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1522))';使用静态监听
这里总结一下配置dgbroker过程中需要用到的几个service。
通过StaticConnectIdentifier配置的地址只会被Broker本身使用,这个地址不会作为其他用途来使用。同时要注意不要使用DGB service,这个服务仅供Broker使用,另外也不允许在TNSNAMES.ORA里配置
_DGMGRL
和_DGB
的服务
在DG Broker中管理的每一个primary和standby库都需要配置一个静态监听条目,也就是StaticConnectIdentifier,这个被Broker用来去连接到远端数据库进行关闭和重启的操作,具体如下:
- 从primary库swithover成物理备库
- 在failover以后重建primary库
- 将snapshot standby转换成物理备库
要去访问一个已经关闭掉的数据库时,Broker默认会使用LOCAL_LISTENER
里的信息和关键字"_DGMGRL“,来生成一个默认的StaticConnectIdentifier值,不建议用户自行去修改这个参数,因为这个值会被Broker自动更新。
针对不同的场景,对应的静态监听配置也不一样。
单实例
1 | SID_LIST_LISTENER= |
RAC One Node
1 | SID_LIST_LISTENER= |
RAC
1 | SID_LIST_LISTENER= |
StaticConnectIdentifier
如果用户手动修改了这个参数,那么Broker会认为用户从现在开始以后都会自行修改,如果实例从一个不同的host启动时,broker则无法连接到对应关闭的实例上。
同样的道理,当LOCAL_LISTENER参数被用户修改以后,则它以后也不会自动更新了。另外如果数据库被加入到DG Broker以后,用户再对LOCAL_LISTENER进行修改,则原有的StaticConnectIdentifier参数并不会同步更新来对应最新的LOCAL_LISTENER值。
如果确实有修改LOCAL_LISTENER参数的需要,则Broker配置也需要手动来操作,恢复StaticConnectIdentifier的自动更新机制:
- 对于standby库使用DGMGRL CLI移除数据库然后重新添加
- 对于primary库使用DGMGRL CLI移除整个配置然后重新创建