Oracle 21c监听器远程连接失败主因是listener.ora中HOST设为localhost或127.0.0.1,导致仅绑定回环地址;须改为实际IP或可解析主机名,并stop/start监听器生效,同时确保hostname与hosts文件匹配、监听器名称一致、SERVICE_NAME与v$parameter查询值完全相同。
listener.ora 里 HOST 写 localhost 就连不上远程客户端
oracle 21c 静默安装或 netca 图形向导生成的 listener.ora,默认常把 host 设为 localhost 或 127.0.0.1。这会导致监听器只绑定到回环地址,本地 sqlplus / as sysdba 能连,但 navicat、pl/sql developer 或其他机器上的客户端一律连接失败,报 ora-12154 或直接超时。
必须改成服务器实际网卡 IP(如 192.168.161.120)或一个客户端能 nslookup 解析的主机名(如 db21c-prod)。改完不能只 lsnrctl reload——该命令对 HOST 变更无效,必须先 lsnrctl stop 再 lsnrctl start。
验证是否生效:netstat -tlnp | grep :1521(Linux)或 netstat -ano | findstr :1521(Windows),输出中应含 *:1521 或具体 IP:1521,而非 127.0.0.1:1521。
HOST 值依赖系统 hostname 和 hosts 文件双向匹配
即使你写了真实 IP,若系统 hostname 返回 bogon 或无法解析的名称(比如 DHCP 分配的临时名),监听器启动时仍可能在日志中报 TNS-00505: Hostname lookup failure 或卡在 “Starting / Waiting”。
检查并修复两处:
- 运行
hostname确认当前主机名;若为bogon或乱码,需修改/etc/sysconfig/network(Linux)或系统属性(Windows) - 编辑
/etc/hosts(Linux/macOS)或C:\Windows\System32\drivers\etc\hosts(Windows),确保有形如192.168.161.120 db21c-prod的条目,且该行在127.0.0.1 localhost之后(避免覆盖) - Windows 用户特别注意:Docker Desktop 安装后常在
hosts文件末尾追加127.0.0.1 localhost以外的干扰项,删掉即可
监听器名称不一致导致 lsnrctl 命令查不到状态
netca 或静默安装有时会生成非默认监听器名,例如 LISTENER_ORCLCDB,但用户仍习惯执行 lsnrctl status(默认查 LISTENER),结果返回 TNS-12541: No listener,误判为没启动。
正确做法:
- 打开
$ORACLE_HOME/network/admin/listener.ora,找到第一行类似LISTENER_ORCLCDB =的定义 - 所有命令必须显式带上该名:
lsnrctl status LISTENER_ORCLCDB、lsnrctl stop LISTENER_ORCLCDB - 不想换名?可统一改为
LISTENER,但要同步修改listener.ora全局名称 + 重启监听器
tnsnames.ora 里的 SERVICE_NAME 必须和数据库注册值完全一致
监听器起来了、HOST 也对了,但客户端连上后报 ORA-12514: TNS:listener does not currently know of service requested,大概率是 tnsnames.ora 中的 SERVICE_NAME 填错了。
不要猜,不要抄模板,登录数据库执行:
SELECT value FROM v$parameter WHERE name = 'service_names';
复制返回值(通常是 ORCLCDB 或带域名的完整名如 orclpdb1.example.com)填入 tnsnames.ora 对应条目的 SERVICE_NAME 字段。注意:
- Oracle 21c 默认是 CDB+PDB 架构,绝对不用 SID;填 SID 必报 ORA-12514
-
tnsnames.ora必须放在$TNS_ADMIN目录下;若未设该变量,则默认找$ORACLE_HOME/network/admin - 改完可用
tnsping ORCL(别名)快速验证网络层通不通,但不校验服务名是否注册成功
最易被忽略的是:监听器启动后,数据库实例必须处于 OPEN 状态,且 LREG 进程完成动态注册,lsnrctl status 输出的 Services Summary 里才会有对应服务名。如果 STATUS 是 UNKNOWN,说明注册失败——先确认 select status from v$instance; 返回 OPEN,再等 30 秒或手动执行 alter system register;。


















