备库必须配静态监听,因为其通常处于MOUNT状态,PMON仅在OPEN时动态注册服务,重启后服务名消失导致ORA-12514;静态监听通过listener.ora硬声明GLOBAL_DBNAME,不依赖实例状态,确保DG Broker及归档传输可靠连接。
备库必须配静态监听,否则实例重启后监听无法自动注册服务,客户端连接直接失败。
为什么备库不能只靠动态监听
Oracle 默认启用 PMON 动态注册,但这个机制依赖数据库实例已启动且能主动向监听进程发送注册请求。而 Data Guard 备库在 STARTUP MOUNT 状态下(这是正常物理备库的运行状态),PMON 不会注册服务名 —— 它只在 OPEN 状态才注册。这意味着:一旦监听进程重启、或备库实例重启,SERVICE_NAME 就从监听里消失,tnsping 通但 sqlplus /@xxx 报 ORA-12514: TNS:listener does not currently know of service requested in connect descriptor。
静态监听绕过 PMON,靠 listener.ora 里的 SID_DESC 在监听启动时就“硬声明”服务存在,不依赖实例当前状态。
- 动态监听注册只发生在
OPEN状态,备库通常不OPEN - 监听进程重启后,动态注册不会自动恢复,除非实例再次
OPEN - DG Broker(
dgmgrl)连接备库也依赖该静态服务名,如db_unique_name_DGMGRL
listener.ora 中静态监听的关键配置项
核心是两块:监听地址定义 + 静态实例注册。不要照搬默认 LISTENER 名称,建议为 DG 单独起名(比如 LISTENER_DG),避免和主库或其他监听冲突。
以下为备库 listener.ora 必须包含的内容(路径:$ORACLE_HOME/network/admin/listener.ora):
LISTENER_DG =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oradg)(PORT = 1522))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1522))
)
)
<p>SID_LIST_LISTENER_DG =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = hisdbdg) <-- 必须与 tnsnames.ora 中 SERVICE_NAME 一致
(ORACLE_HOME = /usr/local/oracle/product/11.2.0/db_1)
(SID_NAME = oradg) <-- 必须与 v$database.name 或 ORACLE_SID 一致
)
)</p><p>ADR_BASE_LISTENER_DG = /usr/local/oracle-
PORT建议避开 1521(主库常用),用 1522 或其他空闲端口,防止端口冲突 -
GLOBAL_DBNAME是客户端连接串里SERVICE_NAME的值,不是DB_NAME;DG Broker 要求它等于db_unique_name+_DGMGRL(例如dghfdb_DGMGRL) -
SID_NAME必须和操作系统环境变量ORACLE_SID完全一致,大小写敏感 - 改完后执行
lsnrctl reload LISTENER_DG,不是stop/start,避免连接中断
tnsnames.ora 与监听的对应关系
客户端(包括主库的 LOG_ARCHIVE_DEST_2、dgmgrl、DBA 手动连接)靠 tnsnames.ora 找到备库监听地址和服务名。它必须和 listener.ora 中的配置严格匹配:
HISDBDG =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oradg)(PORT = 1522)) <-- PORT 必须和 LISTENER_DG 一致
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = hisdbdg) <-- 必须等于 listener.ora 中 GLOBAL_DBNAME
)
)- 如果
tnsnames.ora里写的是PORT = 1521,但监听实际跑在 1522,tnsping HISDBDG就会超时 - 如果
SERVICE_NAME = hisdbdg,但listener.ora里GLOBAL_DBNAME = dghfdb,tnsping成功但sqlplus报ORA-12514 - 主库
LOG_ARCHIVE_DEST_2中的SERVICE=值,也必须指向这个tnsnames.ora别名
验证静态监听是否生效
别只信 lsnrctl status 显示 “Status: READY” —— 那只是监听进程活着。要确认服务名真被静态注册了,得看输出里有没有你配的 GLOBAL_DBNAME:
执行:lsnrctl status LISTENER_DG
正确输出中必须包含类似这一行:
Service "hisdbdg" has 1 instance(s). Instance "oradg", status UNKNOWN, has 1 handler(s) for this service...
- 注意
status UNKNOWN是正常的 —— 这恰恰说明是静态注册(动态注册显示READY) - 如果没看到你的
GLOBAL_DBNAME,检查SID_LIST_LISTENER_DG拼写、大小写、括号嵌套是否完整 - 常见低级错误:
SID_LIST_LISTENER_DG写成SID_LIST_LISTENER(少了个_DG),导致配置被忽略 - 修改前务必备份原
listener.ora,Oracle 对格式极其敏感,多一个空格或少一个括号都会让整个文件失效
最易被忽略的一点:静态监听配置后,tnsnames.ora 和 listener.ora 必须在所有用到它们的地方同步更新 —— 主库的 tnsnames.ora、备库自己的 tnsnames.ora、DG Broker 配置脚本里写的连接串,三者 SERVICE_NAME 和端口必须完全一致。


















