备库必须配置静态监听,否则DG Broker无法连接、switchover失败;因MOUNT状态下PMON不注册服务,动态监听无法提供db_unique_name_DGMGRL服务,而静态监听通过listener.ora硬编码SID_DESC,确保MOUNT/NOMOUNT下仍可响应。

备库必须配置静态监听,否则 DG Broker 无法连接、switchover 会失败、甚至 DGMGRL 连不上备库 —— 这不是可选步骤,是强制前提。
为什么必须用静态监听而不是动态注册
动态注册依赖 PMON 进程向监听器上报服务状态,但备库在 MOUNT 状态下 PMON 不活跃(只在 OPEN 状态才注册),导致监听器查不到 db_unique_name_DGMGRL 这个关键服务名。DG Broker 启动时会尝试连接这个服务名,连不上就报 ORA-12514: TNS:listener does not currently know of service requested in connect descriptor。
静态监听则绕过 PMON,靠 listener.ora 里硬编码的 SID_DESC 直接暴露服务,哪怕数据库是 MOUNT 或 NOMOUNT 状态也能响应连接请求。
- 动态注册的服务名默认是
db_unique_name(如adgdbstandby),但 DG Broker 要的是db_unique_name_DGMGRL - 静态注册后,
lsnrctl status输出中该服务的状态显示为UNKNOWN,这是正常且必要的标识 - Oracle 12c+ 中 LREG 进程也无法在备库 MOUNT 状态下完成 DGMGRL 服务注册
listener.ora 中 SID_LIST_LISTENER 的写法要点
核心是让监听器“知道”有一个名为 db_unique_name_DGMGRL 的服务,对应到本地实例,并指定正确的 ORACLE_HOME 和 SID_NAME。
以主库 db_unique_name=adgdb、备库 db_unique_name=adgdbstandby 为例,备库的 listener.ora 必须包含:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = adgdbstandby_DGMGRL)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1)
(SID_NAME = adgdbstandby)
)
)
-
GLOBAL_DBNAME必须是db_unique_name+_DGMGRL,大小写严格匹配(adgdbstandby_DGMGRL,不是ADGDBSTANDBY_DGMGRL) -
SID_NAME是备库实际的ORACLE_SID(不是db_name,也不是service_name) -
ORACLE_HOME路径必须绝对准确,不能用变量(如$ORACLE_HOME),也不能漏掉末尾斜杠 - 如果备库是 RAC 单实例(即非 RAC 架构但装在 RAC 节点上),仍按单实例方式配,不加
(INSTANCE_NAME = ...)
tnsnames.ora 配置与监听 reload 的验证顺序
只改 listener.ora 不够,客户端(包括 DG Broker)要能解析服务名,还得在 tnsnames.ora 里配好别名。而且顺序错了,lsnrctl status 看起来正常,实际还是连不上。
- 先在备库
tnsnames.ora中添加条目,例如:adgdbstandby_DGMGRL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = standbynode)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = adgdbstandby_DGMGRL))) - 再执行
lsnrctl reload(不是stop/start,避免中断已有连接) - 立刻运行
lsnrctl status,确认输出里有Service "adgdbstandby_DGMGRL" has 1 instance(s),且状态为UNKNOWN - 最后用
tnsping adgdbstandby_DGMGRL测试解析和端口可达性;再用sqlplus sys@adgdbstandby_DGMGRL as sysdba实测能否登录(此时数据库应处于 MOUNT 状态)
最容易被忽略的是:GLOBAL_DBNAME 拼写错误、SID_NAME 填成了 db_name、ORACLE_HOME 路径多一个空格或少一级目录 —— 这些都会让监听器加载时静默跳过该 SID_DESC,status 里根本不会显示那条服务。别信“改完 reload 就好了”,一定要亲眼看到 UNKNOWN 状态的服务名出现在 lsnrctl status 输出里。


















