十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Oracle监听配置全解:从listener.ora到ORA-12514排查

Oracle监听配置全解:从listener.ora到ORA-12514排查 搞数据库的人十有八九都会在 Oracle 监听配置上栽过跟头。明明客户端网络没问题、数据库实例也起来了偏偏 sqlplus 一敲回车就报 ORA-12514或者干脆提示“无监听程序”。说实话监听这个东西刚接触时确实容易一头雾水因为它既不像 SQL 那样有明确的语法规则也不像表空间那样有直观的物理文件几乎全靠一组文本配置文件在协调。但只要你把监听器的工作机制和那三个配置文件的分工弄明白后面再遇到问题基本就是按图索骥的事。这篇文章我打算从监听器的工作原理讲起再把 listener.ora、tnsnames.ora、sqlnet.ora 这几个核心文件的配置逐一拆开最后整理一份高频故障的排查实录包括 ORA-12514、ORA-12541、窗口服务起不来这类经典问题。无论你是刚入门的新手还是被监听折腾过几次的半个老手按这个思路走一遍Oracle 监听配置这条路上的坑基本都能提前避开了。1. 监听器到底在干什么先弄懂这三个配置文件的分工1.1 监听器不是数据库它是数据库的“前台”很多新手容易把监听器Listener和数据库实例混在一起其实监听器是一个独立运行的进程它的职责非常简单在服务器上监听某个端口默认 1521接收客户端的连接请求然后把请求交给对应的数据库实例去处理。你可以把它想象成酒店前台——客户到店先找前台登记前台再通知客房部安排入住。数据库实例就是客房部监听器本身不存储数据、不执行 SQL只负责“接客”和“转交”。这套设计是典型的 CS 架构。客户端比如 PL/SQL Developer、Navicat或者另一台服务器上的程序要连数据库第一步一定是先通过网络找到监听器再由监听器确认它要连接的服务名Service Name是否可用可用的话就建立一条通道客户端才真正和数据库实例对话。Oracle 网络相关的核心配置涉及三个文件文件位置作用listener.ora服务器端$ORACLE_HOME/network/admin/定义监听进程自己的行为比如监听哪个 IP、哪个端口、服务哪些实例tnsnames.ora客户端和服务器端都有定义连接描述符即客户端通过什么协议、地址、服务名去连接数据库sqlnet.ora客户端和服务器端都有控制网络连接的行为比如加密、超时、诊断级别、外部命名等这三个文件里listener.ora 是“服务器端视角”tnsnames.ora 是“客户端视角”sqlnet.ora 是连接策略层。大多数监听配置问题归根到底就是这三个文件里的参数对不上——比如客户端 tnsnames.ora 里写的服务名在服务器端监听器里压根没注册过那 ORA-12514 基本就跑不掉了。1.2 动态注册和静态注册的区别监听器要知道“有哪些服务可以连接”有两种途径动态注册和静态注册。动态注册是默认方式。数据库实例启动后实例里的 PMON 后台进程会自动去向监听器注册告诉监听器“我在这个主机上实例名是什么服务名是什么”。所以只要实例是正常启动的监听器是开着的一般等个几十秒lsnrctl services就能看到自动注册上来的服务。这也是为什么有时候刚启动完数据库立刻连不上过一会儿又能连上了——可能不是网络问题只是 PMON 还没来得及注册。静态注册则需要你在 listener.ora 里手动写SID_LIST_LISTENER段把数据库实例的信息明确写进去。这样即使实例还没启动监听器也知道有这么一个服务存在能做到“只监不听”——客户端可以连上监听器但实例没起来时连接会报“无可用服务”。那静态注册有什么用最常见的场景是 RAC 环境或者需要远程启动数据库实例的时候。实例都没起来PMON 自然没法注册这时候想通过客户端远程执行startup就得靠静态注册先让监听器认识这个库客户端才能连上监听器并把命令传过去。后面的排障部分我也会提到有些特殊场景下静态注册还是救命的。提示动态注册的“服务名”通常来自数据库参数SERVICE_NAMES默认就是 db_unique_name 加域名而静态注册的 SERVICE_NAME 是 listener.ora 里你自己写的二者如果不一致就会出现“监听器认得我但转接不到实例”的怪现象。2. 手把手配置监听图形界面和手工修改两条路2.1 用 netca 图形界面配置监听最快的方式Oracle 自带了一个专门用于网络配置的图形化工具netcaNet Configuration Assistant在服务器上执行命令就能调出图形界面。Linux 服务器通常没有图形桌面可以先用 X 转发比如 Xmanager、MobaXterm 的 X 转发打开界面也可以在有图形界面的 Windows 服务器上直接安装。如果环境限制实在没法打开图形界面那就直接手工改配置下一节会详细讲。用 netca 配置监听器的步骤很简单在命令行执行netca进入图形界面后选择“Listener configuration”。选择“Add”添加新的监听器指定监听器名称默认叫LISTENER。选择协议默认 TCP。填写端口号默认 1521。界面会让你选择“配置该监听器所服务的数据库吗”推荐选“否”因为现代 Oracle 更依赖动态注册这里不配置也不影响实例启起来 PMON 会自动过来注册。完成之后netca 会帮你生成listener.ora文件并尝试启动监听器。用 netca 的好处是它会自动处理很多细节比如文件格式、换行、权限等不容易因为手误写错语法。但它也有局限——netca 通常只生成最基础的配置如果你想加多个监听端口、做多个实例的静态注册、或者改日志目录还是得回到手工编辑文件上来。2.2 手工编写 listener.ora 参数详解如果不想依赖图形界面或者需要做更精细的定制直接编辑$ORACLE_HOME/network/admin/listener.ora是完全可行的。这里给一个最典型的完整示例LISTENER (DESCRIPTION_LIST (DESCRIPTION (ADDRESS (PROTOCOL TCP)(HOST db-server)(PORT 1521)) ) ) SID_LIST_LISTENER (SID_LIST (SID_DESC (GLOBAL_DBNAME orcl.example.com) (ORACLE_HOME /u01/app/oracle/product/19.3.0/dbhome_1) (SID_NAME orcl) ) )先看LISTENER这一段。最外层是监听器的名字默认LISTENER名字可以随便起但为了省事一般都用默认的。DESCRIPTION_LIST里面可以放多个DESCRIPTION每一个 DESCRIPTION 里的 ADDRESS 就是监听器要绑定的地址。如果服务器有多网卡你只想监听其中一张网卡就把 HOST 写成那个网卡的 IP 或主机名如果想所有网卡都听HOST 可以写成0.0.0.0注意某些平台和版本对通配符支持不一样稳妥起见还是写明确的主机名或 IP。再看不带SID_LIST的情况。如果 listener.ora 里只有LISTENER段、没有SID_LIST_LISTENER那么监听器只靠动态注册来发现服务绝大多数单机环境这样也够用。而SID_LIST_LISTENER这段就是上一节说的静态注册配置里面每个SID_DESC描述一个实例SID_NAME数据库实例名对应instance_name。GLOBAL_DBNAME对外提供的服务名对应service_names。客户端 tnsnames.ora 里写的是哪个名字这里的行为就要匹配上。ORACLE_HOME数据库软件的安装路径必须写对否则监听器加载实例时会报错。注意listener.ora 对格式比较敏感多一个括号、少一个换行都可能导致监听器启动失败。改完之后用lsnrctl reload重新加载配置虽然没有重启那么彻底但对多数字段修改都生效而且不会中断已经建立的连接。注意手工修改完 listener.ora 后如果lsnrctl reload报错或者显示的状态不对先执行lsnrctl stop和lsnrctl start重启监听器。但重启会断开正在使用的连接生产环境务必放在维护窗口操作。2.3 启动、停止和查看监听状态监听器最常见的操作命令就是lsnrctl这是一个命令行工具和 sqlplus 类似进入后执行对应命令即可。也可以在命令行直接拼参数执行# 启动默认监听器 lsnrctl start # 停止监听器 lsnrctl stop # 查看监听状态这个用得最多 lsnrctl status # 查看当前监听器登记了哪些服务 lsnrctl serviceslsnrctl status的输出里要重点关注几项Listener Parameter File当前加载的 listener.ora 路径。Listening Endpoints Summary监听器实际监听的地址和端口。Services Summary已经注册到监听器的服务列表包含实例名和服务名。如果在 Services Summary 里看不到你要连的那个服务那客户端连接报 ORA-12514 就一点都不奇怪——监听器压根不知道有这个服务存在。3. 客户端连接与 tnsnames.ora监听配好却连不上的第二战场3.1 tnsnames.ora 写法与常用连接方式服务器端的监听器配置好了接下来就是客户端的连接。Oracle 客户端连接到数据库时默认会读tnsnames.ora文件把连接别名翻译成实际的协议、地址、服务名。文件位置在$ORACLE_HOME/network/admin/下Windows 客户端一般在%ORACLE_HOME%\network\admin\下也可能在%TNS_ADMIN%指定的目录里。如果你找不到文件在哪儿在 sqlplus 里执行show parameter tns_adminLinux 环境可以echo $TNS_ADMIN如果 TNS_ADMIN 没设置就默认使用$ORACLE_HOME/network/admin。一个典型的 tnsnames.ora 条目长这样ORCL (DESCRIPTION (ADDRESS (PROTOCOL TCP)(HOST 192.168.1.100)(PORT 1521)) (CONNECT_DATA (SERVICE_NAME orcl) ) )这里有几个容易踩坑的点第一连接别名这里的ORCL是你自己起的名字sqlplus 里sqlplus user/passORCL用的就是这个别名。别名本身不会传给服务器只是本地的一个指路牌。第二HOST 写什么很关键。如果服务器端监听器配置的是主机名而客户端解析不了这个主机名连接就会卡在“正在连接”很久然后超时。最省事的办法是客户端直接写服务器的 IP 地址除非你的 DNS 和 hosts 文件都调得很明白。第三CONNECT_DATA里的连接标识符有两种写法SERVICE_NAME或SID。新版 Oracle 的默认推荐是SERVICE_NAME因为它对应服务名可以承载 RAC 多个实例负载均衡等特性。但如果你在 listener.ora 里静态注册用的是SID_NAME而不是GLOBAL_DBNAME客户端又用 SERVICE_NAME 去连就可能出现服务对不上报 ORA-12514 的情况。排查思路很简单lsnrctl services里显示什么名字客户端就填什么名字。3.2 验证连通性的两把“尺子”tnsping 和 lsnrctl status配置完 tnsnames.ora 之后第一件事就是用tnsping验证一下客户端能不能通过这条路径找到监听器# 使用 tnsnames.ora 里的别名 tnsping ORCL # 也可以直接写完整连接描述符 tnsping 192.168.1.100:1521/orcltnsping的作用是检查网络通不通、监听器在不在但要注意它只验证到监听器这一层不会验证数据库实例是否可用、账号密码是否正确。所以 tnsping 通了只能说明“前台有人”没法保证“客房能入住”。真正要连数据库还是得 sqlplus 直接上去sqlplus user/passwordORCL或者不依赖 tnsnames.ora直接用 EZCONNECT 方式sqlplus user/password192.168.1.100:1521/orclEZCONNECT 是 Oracle 10g 以后引入的简化连接方式格式就是host:port/service_name不需要配置 tnsnames.ora 就能连接。如果你自己临时调试、不想动配置文件这个方式非常方便。3.3 sqlnet.ora 对连接行为的影响sqlnet.ora 虽然不像前两个文件那么常被改动但里面有几个参数在排查时会用到# 设置客户端连接超时时间单位秒避免网络不通时傻等 SQLNET.OUTBOUND_CONNECT_TIMEOUT 10 # 设置服务器端接收客户端连接的超时时间 SQLNET.INBOUND_CONNECT_TIMEOUT 10 # 诊断级别出问题时临时加大 TRACE_LEVEL_CLIENT SUPPORT TRACE_FILE_CLIENT client.trc比如你连接数据库时总是在输入账号密码那一步卡很久或者老是报连接超时可以检查一下是不是SQLNET.OUTBOUND_CONNECT_TIMEOUT值设得过大。这个文件里还有一个参数NAMES.DIRECTORY_PATH决定客户端按什么顺序去解析连接标识符TNSNAMES、EZCONNECT、LDAP 等如果你把 TNSNAMES 从列表里去掉那 tnsnames.ora 就失效了这也算是个隐蔽的坑。提示排查连接问题时记得客户端和服务器端的 sqlnet.ora 都可能影响行为。尤其一些安全加固文档会建议在 sqlnet.ora 里加访问控制参数比如 TCP.VALIDNODE_CHECKING配置不当会把合法客户端也拦在外面表现为“能 ping 通监听但连接被拒”。4. 高频故障实录监听相关的那些“老坑”4.1 ORA-12514监听服务当前无法识别请求的服务ORA-12514 绝对是监听配置问题里出现频率最高的一条报错完整信息是“ORA-12514: TNS:listener does not currently know of service requested in connect descriptor”。意思是客户端请求的服务名监听器这边不认识。我实际排查过不少这种问题归纳下来就三方面原因第一客户端 tnsnames.ora 里填的 SERVICE_NAME 和数据库真实的 SERVICE_NAMES 不一致。这种最隐蔽因为看起来所有配置都“好像没问题”。解决方法是登录数据库执行show parameter service_names然后用查出来的服务名去改客户端的 tnsnames.ora。第二实例刚启动PMON 还没来得及动态注册。这种通常是启动后立刻连报 12514等个几十秒再试就正常。如果想加速注册可以在数据库里手动触发alter system register;第三监听器是开着的但动态注册失效了比如监听端口不是默认 1521而实例的LOCAL_LISTENER参数没设置到对应端口。实例默认只往 1521 注册如果你把监听器改到 1522PMON 并不知道自然不会跑去注册。这种情况需要设置alter system set local_listener(ADDRESS(PROTOCOLTCP)(HOST192.168.1.100)(PORT1522)) scopeboth; alter system register;排查 ORA-12514 时最快的方式是搞清楚“你连的服务名是什么”和“监听器实际登记的服务名是什么”两张表一对比就知道问题出在哪一环。lsnrctl services的输出就是第二张表。4.2 监听服务无法启动 / ORA-12541无监听程序ORA-12541 和 12514 不一样它表示客户端根本找不到监听器——连接被拒绝或者目标端口上压根没有程序在监听。出现这种问题先分两层查第一层确认监听器进程到底有没有起来。在服务器上执行lsnrctl status如果提示TNS-12541: TNS:no listener说明监听器没在运行直接lsnrctl start启动。Linux 下如果启动时报权限错误或者端口被占用用netstat -tlnp | grep 1521看看端口有没有被别的程序占着。第二层端口通不通。在客户端上用telnet 服务器IP 1521连不上就说明网络层有问题可能防火墙挡了。Linux 上常见 iptables 或 firewalld 没放行 1521 端口Windows 服务器则要检查防火墙入站规则。生产环境改防火墙策略要谨慎最好先和管理员沟通好别为了调试把安全规则给松了。还有一个非常隐蔽的问题Windows 服务列表里 Oracle 监听服务服务名通常是OracleOraDB19Home1TNSListener显示“已启动”但lsnrctl status却报没有监听器。这种情况经常是服务启动时加载的是另一个listener.ora文件——比如 TNS_ADMIN 环境变量指向了别处或者注册表配置的 ORACLE_HOME 对不上。处理办法是先把服务的启动参数对齐到真实路径或者直接在命令行手动lsnrctl start看它到底加载了哪个配置文件。注意Windows 下改过 listener.ora 后建议不要只重启 Windows 服务最好在命令行用lsnrctl stop和lsnrctl start彻底重启一次。Windows 服务的启动和停止有时候不会真正重新加载配置文件尤其是 Oracle 11g 之前的老版本这个问题坑过不少人了。4.3 ORA-28547连接服务器失败疑似 Oracle Net 管理错误ORA-28547 这条报错相对小众它通常出现在尝试通过外部过程、异构连接比如 Oracle 通过透明网关连接 SQL Server或者某些数据库链接访问外部数据源的场景。报错信息里往往会带上probable Oracle Net admin error含义是监听器这边没法正确处理这个连接请求。一般情况下先检查 sqlnet.ora 里的协议和相关配置再看外部过程external procedure的监听是否正常。查看监听器的 services 输出确认有没有对应的extproc服务lsnrctl services | grep -i extproc如果看不到 extproc 相关条目可能需要在 listener.ora 里补上类似这样的配置SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME extproc) (ORACLE_HOME /u01/app/oracle/product/19.3.0/dbhome_1) (PROGRAM extproc) ) )当然更常见的场景是外部过程连错了监听器或者多个数据库实例竞争同一个 extproc 条目。这种问题排查起来比较费时间关键是先定位到底是谁在调用外部过程再对着监听器服务的登记信息逐一排除。4.4 多实例注册到同一个监听器为什么连到了别人的实例企业生产环境里一台服务器上装多个 Oracle 实例并不罕见如果都用同一个默认监听器就会出现“服务名指向 A 实例结果连到 B 实例”的诡异场景。原因在于动态注册的机制只要数据库参数SERVICE_NAMES和监听器端口匹配PMON 就会把自己的服务注册上去。如果 A 实例的服务名恰好和 B 实例重复了后注册的实例可能会覆盖先注册的条目客户端一连接就落到了 B 实例上。解决办法是规划好服务名的命名尽量让每个实例的服务名全局唯一如果实在没法改就老老实实给每个实例配独立的监听器端口比如实例 A 监听 1521实例 B 监听 1522。实例 B 这边通过LOCAL_LISTENER参数指定往 1522 注册即可客户端也各自连各自的端口彻底物理隔离。5. 监听运维的几个实用技巧5.1 日志与 trace监听出问题的第一手证据监听器运行过程中会写日志默认位置在$ORACLE_HOME/network/log/listener.log。你可以打开这个文件实时跟踪连接请求tail -f $ORACLE_HOME/network/log/listener.log当客户端连接报错时日志里会记录对应的错误码和目标服务名比如 12514 就会在日志里留下 “service not known” 之类的信息。这比猜配置要直接得多。如果你希望日志单独放一个目录防止和默认目录混在一起可以在 listener.ora 里加上LOG_DIRECTORY_LISTENER /u01/app/oracle/admin/listener_log LOG_FILE_LISTENER listener每次改动 listener.ora 后记得lsnrctl reload或重启监听器让参数生效。5.2 reload 与 restart什么时候用哪个lsnrctl reload和lsnrctl restart是监听器运维里最常用的一对命令但很多人并不清楚它们的区别。reload重新读取 listener.ora 配置但不会关闭已经建立的连接。对已经连上的会话影响极小适合改动端口、日志目录、新增服务这类场景。restart等于先 stop 再 start监听器会短暂中断所有正在通过该监听器建立的连接都会被断开。涉及监听端口本身变更、配置语法严重异常、或者监听器进程挂死的时候才需要用。生产环境能 reload 就不 restart这是基本的操作纪律。但如果你改的是 PORTreload 不一定生效有些版本需要 restart 才能重新绑定端口以实际状态为准。5.3 开机自启与多实例管理Linux 环境下Oracle 监听器通常由oracle用户启动可以通过lsnrctl start手动启动也可以在数据库启动脚本里一并拉起。如果你用的是 Oracle RestartGI监听器会被独立管理可以用crsctl status res ora.listener.listener查看状态。这种方式下最好不要手动用 lsnrctl 去启停监听器容易和集群资源管理产生冲突。多实例环境下每个实例往同一个监听器注册是正常行为。查看lsnrctl status时Services Summary 下方会出现多个实例的注册信息。只要服务名不冲突一般不用特别干预。但要注意实例关闭后PMON 会注销服务但监听器里的注册信息可能存在一个短暂的空窗期表现为“实例已经关了客户端连接却卡住很久才报错”这和监听器本身没关系。5.4 快速判断“问题出在客户端还是服务器端”我每次排查监听问题都会先做一个简单定位在服务器本机用 sqlplus 连一次。如果本机能连、客户端不能连问题基本在网络上如果本机也连不上问题基本在监听器或数据库本身的配置上。本机验证命令sqlplus user/passwordlocalhost:1521/orcl或者进入 sqlplus 后用斜杠连接sqlplus / as sysdba再执行select instance_name, status from v$instance;确认数据库实例本身是 OPEN 状态。实例都没起来监听配置再完美也是白搭。写在最后的几点实在话监听配置这个问题说难也难说简单也简单。难在牵扯的环节太多——网络、主机名解析、配置文件格式、实例注册机制任何一个环节出岔子都会报出让人摸不着头脑的错误。简单在只要你形成一套固定的排查路径先看监听器状态再看服务注册情况然后看客户端解析对不对最后看网络通不通九成以上的问题都能在这个流程里定位到。我自己踩过最深的坑是有一次在一台 CentOS 服务器上折腾了大半天怎么连都报 ORA-12514最后发现是数据库的SERVICE_NAMES带了默认域名后缀而客户端的 tnsnames.ora 里只写了短服务名两边差了那么几个字符。从那以后我排查监听问题第一步永远是先核对双方的服务名是否完全一致一个字符都不能差。另外一个建议是动手改配置之前先把原始的 listener.ora 备份一份。这文件虽然不长但手工编辑时一个括号、一个缩进的差异就够你折腾一晚上。用cp listener.ora listener.ora.bak这种操作不费什么时间关键时刻却非常管用。最后再分享一个小技巧不管是什么版本的 Oracle配置完监听后都养成一个习惯lsnrctl services和tnsping各执行一次确认服务和网络两层都通了再交给业务去验证。多花这一点点时间能帮你省掉后面无数个“为什么连不上”的深夜排查。
返回列表