listener.ora中必须写死ip而非host,因监听器仅绑定address块明确列出的ip+端口;host仅为别名,dns解析多ip时仅取首个结果,易绑错;每个ip需独立address,vip须单独配置且已生效;local_listener必须设为客户端可达的ip(如vip),否则pmon注册失败;tnsnames.ora中host应直接写vip ip;优先使用动态注册,避免静态注册状态不可知;改配置后用lsnrctl reload重载。

listener.ora里必须写死IP,别信HOST
监听器启动时只认ADDRESS块里明确列出的IP+端口组合,HOST字段纯属别名,不参与绑定。如果HOST解析出多个IP(比如主机名绑了双网卡或VIP+物理IP),监听器只会取DNS或/etc/hosts返回的第一个结果——大概率绑到127.0.0.1或私网IP,导致远程连不上。
- 每个要监听的IP都得单独写一个
ADDRESS,不能用逗号分隔,也不能复用同一个DESCRIPTION -
ADDRESS=(PROTOCOL=TCP)(HOST=192.168.10.100)(PORT=1521)是对的;HOST=db01是错的,哪怕db01在/etc/hosts里指向正确IP也不行 - 启用VIP时,VIP必须作为独立
ADDRESS加入,且该IP必须已在系统生效(ip addr show能查到)
LOCAL_LISTENER必须设成客户端能访问的地址
数据库实例靠LOCAL_LISTENER参数告诉监听器“我在哪”,设错会导致PMON注册失败,lsnrctl services里看不到服务,客户端查不到实例。
- 值必须是客户端能直接访问的IP,通常是VIP或业务网IP,绝不能是
localhost、127.0.0.1或本地网卡IP - 格式示例:
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.10.100)(PORT=1521))) - 改完后执行:
ALTER SYSTEM SET LOCAL_LISTENER='...' SCOPE=BOTH;,再手动触发注册:ALTER SYSTEM REGISTER; - 验证:运行
lsnrctl services LISTENER,看对应service_name下是否有你的INSTANCE_NAME
tnsnames.ora里HOST别写主机名
客户端连接失败常因tnsnames.ora里HOST写了主机名,而该主机名在客户端DNS或/etc/hosts里被解析成了物理IP而非VIP。
- 最稳妥做法:直接写VIP的IP,例如
HOST=192.168.10.100 - 若必须用主机名,确保客户端
/etc/hosts中该主机名**只映射VIP**,且排在物理IP前面 - Windows客户端还要检查
sqlnet.ora或注册表是否启用了USE_SHARED_SOCKET=TRUE,这会干扰绑定行为
动态注册够用就别碰静态注册
静态注册要手动维护sid_list_LISTENER,监听器无法感知实例启停状态,lsnrctl services里服务状态永远是UNKNOWN,排查问题更难。
- 除非有特殊需求(如外部服务、ADG备库静态监听),否则坚持用动态注册
- 确保
INSTANCE_NAME、SERVICE_NAMES、LOCAL_LISTENER三个参数一致且有效 - 修改配置后,用
lsnrctl reload重载监听器,比stop/start更安全,避免连接中断
真正容易被忽略的是:监听器绑定的是操作系统层面的网络接口,不是Oracle参数里的逻辑名;任何依赖DNS或主机名解析的写法,都在把连接稳定性交给不可控因素。











