ARTICLE DETAIL

资讯详情

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

ORA-12514详解:Oracle监听器不认识服务名的排查与修复

ORA-12514详解:Oracle监听器不认识服务名的排查与修复 1. 这个报错到底在说什么一次数据库连接的完整旅程干了十几年Oracle DBA遇到过无数次ORA-12514: TNS:listener does not currently know of service requested in connect descriptor。每次看到这条提示我都能猜到对方此刻的状态——大概率是客户端工具连着连着突然断掉或者新配了一台机器怎么也连不上数据库百度一搜全是各种帖子照着改了半天还是不行。先别急着动手敲命令咱们把这句话翻译成人话监听器说我不知道你请求的那个服务。这句话的信息量其实很大。它意味着你的网络是通的、主机是通的、端口是通的你甚至已经找到了监听器但监听器在它自己的服务清单里翻来覆去找不到你问的那个名字。要理解这件事得先搞清楚Oracle连接机制里三个角色的分工。客户端、监听器Listener、数据库实例这三者各司其职。客户端拿着一个连接描述符就是你tnsnames.ora里那一大串配置去找监听器监听器是一个独立的进程它守着某个端口默认1521等待连接请求数据库实例是真正干活的进程它启动后会把我在这里我叫什么名字告诉监听器这个过程叫做注册。你可以把这一整套想成酒店的前台。你走进酒店连接数据库前台监听器查了查入住登记表已注册的服务列表告诉你没有你报的房客名字。注意前台本身是正常上班的酒店也住满了人问题出在登记表上根本没有这个名字。搞清楚这个逻辑后面所有排查思路都会清晰很多。ORA-12514本质上是一个查找不到名字的错误而不是门都找不到的错误。这决定了它不是网络问题不是防火墙问题而是服务注册和名称解析的问题。2. 五大经典原因按出现频率排个队几年下来这类报错的原因翻来覆去就那么几类。我按实际遇到频次从高到低排一下你可以对照自己的场景直接跳。2.1 服务名写错了最冤枉的翻车现场这是我最常遇见的场景。开发同事一脸笃定地说我连接串明明没问题结果我把他的连接串复制过来一看服务名少了个字母或者环境名写成了另一个库的名字。Oracle连接描述符里有几个容易搞混的概念。SERVICE_NAME是数据库的逻辑服务名它默认取全局数据库名也就是db_name加db_domain的组合如果你配置了domain的话。SID是实例的唯一标识一个服务名可以对应多个实例比如RAC环境下而一个实例通常只有一个SID。在tnsnames.ora里最常见的是这种写法ORCL (DESCRIPTION (ADDRESS (PROTOCOL TCP)(HOST 192.168.1.100)(PORT 1521)) (CONNECT_DATA (SERVER DEDICATED) (SERVICE_NAME orcl) ) )注意最后一行是SERVICE_NAME orcl这里的orcl指的是数据库的服务名不是SID。很多人在这里误写成SID orcl在某些情况下也能通但两者的解析机制完全不同。用SERVICE_NAME是动态查找用SID是让监听器直接定位到具体实例。报错信息里说的service requested in connect descriptor就是这里指定的值。如果这个值跟数据库实际的服务名对不上监听器必然回你一句我不知道。2.2 数据库实例没注册成功最常见的沉默者数据库启动后PMON后台进程会定期把实例信息注册到监听器上。这是一个动态过程有默认的时间间隔通常60秒一次。如果你数据库刚启动、或者监听器刚重启PMON还没来得及完成注册这个时候连接就一定报ORA-12514。更隐蔽的情况是监听器启动的时候数据库还没起来后来数据库起来了PMON也确实尝试注册了但因为某些原因比如参数配置问题注册失败监听器那边始终查不到这个服务。这种情况你不会在监听器日志里看到报错lsnrctl status显示的服务列表里也没有这个库。2.3 监听器起来了但起的不是你以为的那个这是个非常坑的场景。服务器上装了多个Oracle软件或者同一个实例配置了多个监听端口你执行lsnrctl start启动了一个监听器但它监听的端口可能不是你想连的那个。举例来说你数据库的listener.ora里配了两个监听器一个监听1521一个监听1526。你现在连的是1526但刚才重启的是1521那么1526这个端口上压根没有监听服务在跑。这时候你连1526端口报的往往不是ORA-12514而是ORA-12541无监听器。但如果你以为1526的监听一直在跑实际上它跑的是一个旧的、没有加载你最新配置的监听那就可能出现12514。判断方法很简单lsnrctl status LISTENER_1526看清楚这个监听器到底认不认识你的实例。2.4 数据库确实起来了但处于错误的状态数据库实例启动后可能停在MOUNTED状态还没到OPEN状态。监听器照样能查到服务注册但当你尝试连接时会收到ORA-12514或者ORA-01033之类的错误。这不算监听器的问题而是实例状态的问题。我见过有人折腾了半天监听器配置最后拿sqlplus / as sysdba一看数据库根本没OPEN。这类问题属于服务名能查到但服务不可用的范畴跟12514的报错有时候会交织在一起需要打开日志确认。2.5 动态注册与静态注册的混淆Oracle支持两种注册方式动态注册和静态注册。动态注册是PMON自动上报不需要配置listener.ora里的SID_LIST段。静态注册则需要你在listener.ora手工写明某个SID对应哪个实例。如果你的listener.ora里写了静态注册但写的SID跟实际的SID对不上或者后来改过实例名但忘了改配置文件那监听器会忠实按照配置文件挨个找实例找不到就报12514。反过来如果你依赖动态注册但参数service_names或instance_name的值不是你连接串里写的那个一样报错。这里要记住一句话动态注册靠参数静态注册靠配置。两套机制可能同时生效排查时都要检查。3. 系统化排查路径从上到下不跳步不漏判遇到ORA-12514我最反感的一上来就改配置文件。数据库环境千奇百怪你改之前必须确认问题出在哪个环节。按照下面的顺序走基本能在十分钟内定位问题。3.1 先确认真实报错信息不要只看第一行很多人在客户端工具里看到ORA-12514就以为只有这个错。但有些工具会同时提示更底层的错误比如ORA-12541、ORA-12545、ORA-12560等。完整的错误信息对定位非常有帮助。更严格的做法是不要只靠GUI工具的提示直接在命令行用SQL*Plus测sqlplus username/passwordhost:port/service_name用最原始的连接字符串绕过tnsnames.ora的解析问题。如果这种方式能连上说明数据库和监听器都没问题问题就出在客户端的tnsnames配置上。如果连这也报12514那问题就在服务端。3.2 查监听器状态服务列表里到底有没有在数据库服务器上执行lsnrctl status重点看两栏。第一栏是监听器的基本信息比如端口、主机名确认你连的就是这个监听器。第二栏是Services Summary部分里面列出了这个监听器已知的所有服务。如果你发现你的数据库服务名不在这个列表里那监听器确实不知道这个服务12514没跑。如果服务名在列表里但仍然报12514那就要关注另一个细节服务的状态是READY还是BLOCKED。READY表示实例已经注册完毕可以接受连接BLOCKED表示实例处于某种阻塞状态不能接受新连接比如实例还停在MOUNTED阶段。看到BLOCKED你的方向就该转向检查实例状态了。3.3 查监听器服务明细确认连接方式lsnrctl services命令能看到更细的信息包括每个服务名对应的实例、处理程序类型DEDICATED还是SHARED以及连接数。这个命令对于确认实例是否正常注册非常有效。3.4 查数据库参数服务名和实例名是否匹配如果监听器列表里没有你的服务名接下来要在数据库上确认实例的期望服务名sqlplus / as sysdba SQL show parameter service_names; SQL show parameter instance_name; SQL show parameter db_name; SQL show parameter db_domain;服务名的构成规则是如果db_domain不为空service_names默认就是db_name.db_domain如果为空就是db_name本身。你在连接串里写的SERVICE_NAME必须严格等于service_names参数的值如果有多个则等于其中一个。比如db_nameorcldb_domainexample.com那默认服务名是orcl.example.com。很多开发环境不配domain默认就是orcl。你拿SERVICE_NAMEorcl.example.com去连一个没配domain的库监听起来会认识orcl但不会认识orcl.example.com。3.5 触发手动注册排除时间差如果确认参数没问题但服务列表里还是看不到可以尝试让PMON立刻重新注册一次sqlplus / as sysdba SQL alter system register;执行完过几秒再看lsnrctl status。如果服务列表里出现了你的服务名说明问题就是动态注册的延迟或失败。这时候可以用alter system set service_names...临时改一下触发一下或者检查监听器日志了解PMON注册失败的原因比如LREG进程和监听器的版本不匹配。3.6 查监听器日志判断注册失败根因所有注册尝试都会记录在监听器日志里默认位置是$ORACLE_HOME/network/log/listener.log。看这个日志时重点关注两种记录一是注册请求本身REGISTER相关条目二是连接尝试时的错误码。日志里如果反复出现类似registration with listener ... failed的记录说明PMON确实一直在尝试注册但注册请求被拒。常见原因是监听器的配置里有SID_LIST静态段且静态段的某些参数与动态注册冲突。某些版本还可能出现PMON和监听器的Oracle软件版本不一致导致注册协议不兼容。3.7 用tnsping排除客户端解析问题服务端一切正常但客户端还是连不上时用tnsping测一下客户端到服务端的连通性和描述符解析tnsping your_aliastnsping的作用有限它只能验证网络的连通和描述符的解析它不验证服务名是否存在。也就是说即使tnsping显示成功也不代表能连上数据库。反过来如果tnsping直接报错那问题在网络或描述符配置上。4. 对症下药不同场景的修复方案定位到原因后修复方案就比较明确了。我这里按场景给出实操步骤。4.1 服务名配置错误的修复确认了数据库端的正确service_names后修改客户端tnsnames.ora里的SERVICE_NAME。这里有个实用的技巧用sqlplus的命令行参数直接测不需要反复改文件sqlplus scott/tiger192.168.1.100:1521/orcl把最后一个orcl替换成正确的服务名。能连通就说明网络和监听器都没问题只需要把tnsnames.ora改对即可。4.2 动态注册失败的强制方案很多时候PMON的自动注册会因为各种原因卡住。除了alter system register手动触发还有一种相对可靠的强制做法在数据库里确认service_names参数值。用alter system set service_namesorcl scopeboth;显式指定。执行alter system register;。等10秒再在监听器上执行lsnrctl status确认。如果还是不行可以重启监听器lsnrctl stop然后lsnrctl start给PMON一个全新的注册环境然后再执行alter system register。这里有一个很容易被忽略的细节如果监听器没有监听1521端口而是用了自定义端口那么必须在数据库端设置LOCAL_LISTENER参数否则PMON默认往1521端口注册。比如SQL alter system set local_listener(ADDRESS(PROTOCOLTCP)(HOST192.168.1.100)(PORT1526)); SQL alter system register;检查local_listener的当前值SQL show parameter local_listener;我处理过不少监听在1526数据库怎么都注册不上的案例根因就是这个参数没有指向正确端口。4.3 静态注册的配置方法静态注册适合一些特殊场景数据库实例还没启动但你又希望监听器知道这个服务或者你需要在RAC环境下让监听器分发请求。静态注册在listener.ora里写死SID和ORACLE_HOME具体格式如下SID_LIST_LISTENER (SID_LIST (SID_DESC (GLOBAL_DBNAME orcl) (ORACLE_HOME /u01/app/oracle/product/19.3.0/dbhome_1) (SID_NAME orcl) ) )改完listener.ora后需要重启监听器让它重新加载配置。注意GLOBAL_DBNAME的值要跟你连接串里的SERVICE_NAME一致。如果写错即使SID_LIST配置存在连接时监听器还是会说不认识。静态注册在实例名正确的前提下即使数据库处于SHUTDOWN状态监听器也能接收请求并返回ORA-12514之外的其他错误通常是ORA-01034实例不可用这在某些冷备切换场景下很有用。4.4 多监听器环境的配置修复如果服务器上存在多个监听器或者有多个版本的Oracle最安全的做法是先停掉所有监听器确认所有实例已启动再按顺序启动监听器让PMON逐个注册。或者干脆使用静态注册明确指定端口和实例的对应关系。检查当前所有监听器的状态ps -ef | grep tnslsnr看到几个监听器进程就分别用lsnrctl status 监听器名确认各自的端口和服务注册情况。5. 实践中踩过的坑每个都有血泪代价这一节是我个人遇到过的、教科书上不那么容易被提及的经验希望能帮你避开这些容易让人走弯路的地方。5.1 主机名解析的隐性坑监听器在启动时会把主机名解析成IP地址。如果你的/etc/hosts文件里有冲突条目或者DNS服务器解析不稳定监听器可能会绑定到一个错误地址上。这时候lsnrctl status显示的监听地址会是个奇怪的IP客户端无论怎么连都报12514。排查方法对比lsnrctl status里显示的Host和实际服务器的hostname -i如果对不上就去查/etc/hosts。有些环境里主机名在DNS和/etc/hosts之间解析不一致导致监听器绑到了内网IP而客户端访问的是外网IP或不同网段的IP。这个坑坑了我一次现场折腾了三个小时才定位到是DNS解析问题。以后但凡遇到奇怪的监听问题我都会顺手检查一下hostname和/etc/hosts的一致性。5.2 listener.ora的位置陷阱listener.ora的查找顺序有讲究。它不是固定读一个路径的文件而是根据TNS_ADMIN环境变量和默认路径按顺序查找的。如果你的环境里设置了TNS_ADMIN指向某个目录那么在另一个目录里改listener.ora是没用的。判断你当前生效的配置路径lsnrctl show 1输出里会显示当前使用的配置文件路径。改完配置后执行lsnrctl reload或者lsnrctl stoplsnrctl start让配置生效。5.3 防火墙和iptables的干扰这个场景容易和网络问题混淆。监听器已经正常启动服务也注册了但客户端永远收到12514——因为它根本连不到那个端口。某些云安全组规则或iptables配置会悄悄丢弃到1521端口的包但奇怪的是如果同一个端口你配置了其他服务它可能又是通的。判断方法在客户端机器上执行telnet 主机IP 1521看端口是否能通。如果超时或拒绝赶紧查防火墙和安全组。注意很多时候telnet能通但应用连不上原因是某些应用服务器自身有出站规则限制。这时候要在应用服务器上单独测。5.4 连接串里的空格和特殊字符tnsnames.ora的解析对格式不是特别宽容。括号内部是否包含多余空格、缩进是否对齐理论上不影响理解但如果你的连接串是从网页或邮件里复制粘贴的可能会带入不可见字符特别是中文引号、全角括号这些字符在解析时会导致字段无法识别。我曾处理过一个案例连接串看起来完全正常但就是报12514。最后是用cat -A tnsnames.ora检查发现有一行末尾带了一个无法显示的乱码字符。解决办法是重新手工敲一遍连接串不要复制粘贴。6. 从ORA-12514到关联报错识别错误族系的规律数据库连接报错是个族系很多错误表面相似但原因完全不同。花点时间了解它们的区别排查时能更快锁定方向。6.1 几个容易混淆的TNS错误速查表报错代码含义典型原因排查方向ORA-12514监听器不认识请求的服务服务名写错、未注册、参数不符检查服务注册和service_namesORA-12541没有监听器在目标端口监听器未启动、端口被占用检查监听器进程和端口监听状态ORA-12545连接因目标主机或对象不存在而失败主机名解析失败、主机不可达检查网络、DNS、hostsORA-12560协议适配器错误客户端与服务端版本不匹配、本地服务未运行检查版本兼容性和客户端配置ORA-01034ORACLE不可用实例未启动检查实例状态ORA-12505监听器不认识给定的SIDSID写错而不是service_name检查SID配置从这张表能看到12514和12505是一对姐妹错误12514针对SERVICE_NAME12505针对SID。如果连接串里写了SIDorcl但实际实例名不是orcl报出来的往往是12505。而如果写了SERVICE_NAMEorcl但服务名不匹配报的就是12514。6.2 一次真实压测场景的复盘去年帮客户排过一次比较典型的问题。他们做压测连接池里配置了多个连接串压测进行到一半突然大量报ORA-12514。检查lsnrctl status发现服务列表里两个实例都正常READY状态但应用就是连不上。后来定位到原因应用服务器到数据库服务器的连接数超过了监听器的处理能力上限监听器在高并发下开始拒绝某些连接请求返回的恰恰就是12514。这不是服务未注册的问题而是连接风暴导致的误报。处理方式是调整监听器的队列长度参数以及在应用侧增加连接池的等待时长。这里想提醒你ORA-12514不一定永远是名字问题在高并发环境中也要考虑连接风暴导致的假报错。真到这一步看看监听器日志是不是间歇性出现TNS-12514配合其他错误码比如TNS-12535超时这往往说明压力问题而非注册问题。6.3 版本差异导致的注册失败Oracle 12c之后实例的注册由LREG进程负责早期版本是PMON。如果你混用了不同版本的Oracle软件比如监听器是11g的实例是19c的注册协议可能存在兼容性问题。这种情况下最靠谱的方案就是使用静态注册代替动态注册在listener.ora里把SID和实例的对应关系写死。虽然灵活性差点但在跨版本环境下反而更稳定。7. 最后的经验总结让ORA-12514不再困扰你我处理过的ORA-12514案例少说也有几十个每次流程其实都差不多确认报错原文查监听器状态比对服务名检查注册情况再顺着链路逐步排除。这套流程走下来绝大多数问题都能在十几分钟内解决。这里分享一个实用的小习惯每次搭建新的数据库环境我都会提前在listener.ora和tnsnames.ora里把所有连接信息用静态注册固化下来并记录当时的service_names、instance_name参数。环境出问题的时候拿出来对一下往往一眼就能看出哪里写错了。另一点想说的是数据库的报错信息本身就是最好的排错指引。ORA-12514里的service requested in connect descriptor已经明确告诉你是服务名的问题先别急着重启监听器。很多人在遇到这个错时第一反应就是重启监听但如果没有解决根本原因比如服务名配置错误重启后问题照样存在而且重启本身会切断现有连接带来额外的业务中断。遇到报错先冷静判断范围是单个客户端连不上还是一批客户端都连不上是只有新配置的环境有问题还是原本正常的环境忽然出现这个判断能帮你迅速决定从客户端排查还是从服务端排查。最后再给一个建议如果手头有数据库服务器的SSH权限优先在服务器本机用SQL*Plus连一次sqlplus / as sysdba能进来说明实例没问题。再执行sqlplus system/passwordlocalhost:1521/orcl能进来说明监听器和注册没问题。从服务器本机逐步往外测一层一层缩小范围这是最不会走弯路的排查思路。希望这篇东西能帮你省下几个小时排查时间。记住这个错误的核心逻辑——监听器不认识服务名——然后顺着注册和名称解析这两条线去查问题总能水落石出。
返回列表