☰
15-ORA-12514服务名未注册处理
2026/10/14 3:48:56 网站建设 项目流程

文章目录

  • ORA-12514:服务名未注册处理
    • 报错现象
    • 原因:动态注册是怎么工作的
    • 排查步骤
      • 第一步:看监听器上到底注册了什么
      • 第二步:确认实例和参数
      • 第三步:立即触发注册
      • 第四步:注册目标对不上时,修 local_listener
      • 第五步:主动追加服务名
    • 兜底方案:静态注册
    • 验证与预防
    • 小结

ORA-12514:服务名未注册处理

报错现象

客户端连接被监听器拒绝:

C:\> sqlplus bizapp/Biz2024@orcl SQL*Plus: Release 19.0.0.0.0 - Production on 星期一 9月 28 10:20:11 2026 ERROR: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor

和 ORA-12541 的关键区别:监听器活着(否则报 12541),但它在自己的服务清单里找不到你请求的SERVICE_NAME = orcl。也就是说,问题不在"门开没开",而在"名单上没这个名字"。

原因:动态注册是怎么工作的

服务注册默认由数据库实例自动完成,叫动态注册。承担注册的进程随版本而异:11g 及以前是PMON,12c 起改为LREG(Listener Registration Process):

  • 实例启动后,注册进程把本实例的service_names注册给本机 1521 端口上的监听器;旧版本 PMON 约每60 秒轮询一次,12c 的 LREG 则在实例启动及服务配置变更时注册
  • 监听器收到注册后,才把这个服务加进自己的服务清单,之后指向该服务的连接才能被受理
  • 库关掉时注册进程消失,注册随之消失;监听器重启时清单清空,随后被请求重新注册

由此推出两个高发场景:

场景一:空窗期。机器重启后先起了监听器,数据库 startup 完成后注册可能尚未完成(旧版本 PMON 最多要等 60 秒)。这段窗口内连接全报 12514——库明明是好的。

场景二:注册目标对不上。监听器换了端口(不再是 1521),注册进程还往旧的 1521 注册,服务永远进不了监听器清单;或者库的service_names值和连接串里写的名字不一致(大小写、拼写、域名后缀)。

排查步骤

第一步:看监听器上到底注册了什么

lsnrctl services

正常输出长这样:

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dbserver)(PORT=1521))) 服务 "orcl" 包含 1 个实例。 实例 "orcl", 状态 READY, 包含 1 个此服务的常规处理程序... 处理程序: "DEDICATED" 已建立:1 已被拒绝:0 状态:ready LOCAL SERVER

对照三样东西:

  • 服务名清单里有没有你连接串里SERVICE_NAME的值(区分大小写)
  • 有的话实例状态是不是READY(READY才能接业务连接)
  • 什么都没有——说明注册没发生,继续第二步

lsnrctl status的摘要部分也能看到服务摘要...,信息同理。

第二步:确认实例和参数

sqlplus / as sysdba
SQL> select instance_name, status from v$instance; INSTANCE_NAME STATUS ---------------- ------------ orcl OPEN SQL> show parameter service_names NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ service_names string orcl

如果service_names的值与客户端连接串不一致(比如客户端写orcl,参数是orcl.example.com),改一边对齐即可。

第三步:立即触发注册

SQL> alter system register;

这条命令让注册进程马上执行一轮注册。回头再看:

lsnrctl services

服务出现了,客户端重连,通常就此解决。

第四步:注册目标对不上时,修 local_listener

如果监听器不在默认 1521 端口,注册进程默认只往 1521 注册,alter system register也白搭。查当前值:

SQL> show parameter local_listener

修正为监听器实际地址(接第 10 篇改端口的场景):

SQL> alter system set local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=dbserver)(PORT=2521))' scope=both; SQL> alter system register;

scope=both立即生效且写入 spfile;如果用的是 pfile 启动,改scope=memory并同步改 pfile 文件。

第五步:主动追加服务名

想让同一个实例多挂一个对外服务名(应用按服务名区分用途):

SQL> alter system set service_names='orcl,bizsvc' scope=both; SQL> alter system register;

之后lsnrctl services里会多出bizsvc,客户端可以用SERVICE_NAME = bizsvc连接,落在同一个实例上。

兜底方案:静态注册

动态注册依赖"注册进程活着并完成注册",库没开、刚启动的空窗期、NOMOUNT/MOUNT 阶段都靠不住。想让监听器无条件认识某个 SID,用静态注册:在listener.ora里加SID_LIST_LISTENER:

SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = orcl) (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1) (SID_NAME = orcl) ) ) LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbserver)(PORT = 1521)) ) )

三个参数:

  • GLOBAL_DBNAME:对外提供的服务名,客户端SERVICE_NAME写这个值(或老式写法SID)
  • ORACLE_HOME:实例的安装目录,路径必须真实存在
  • SID_NAME:实例名,即ORACLE_SID

生效:

lsnrctl reload lsnrctl services

静态注册的服务在输出里特征明显——状态是UNKNOWN:

服务 "orcl" 包含 1 个实例。 实例 "orcl", 状态 UNKNOWN, 包含 1 个此服务的常规处理程序...

UNKNOWN 不代表错,只代表"监听器从配置文件背下了这个名字,不保证实例此刻可用"。连接打过来时监听器照样 spawn 一个 server process 去拉起会话,实例没开才会真正失败。

它的真实用途:

  • 远程启动数据库:库是 nomount/idle 状态时,动态注册不存在,只有静态注册能让 DBA 从远程连上来执行 startup(云上运维没有本地终端时是刚需)
  • 兜住重启后动态注册完成前的空窗
  • 一些老版本 OEM / 第三方备份软件要求

局限:静态注册不感知实例真实状态(READY/UNKNOWN 之差),不带负载信息,RAC 环境下不能做服务漂移。动态注册为主、静态注册兜底,两者可以共存于同一个 listener.ora。

验证与预防

验证修复的标准动作,三连:

lsnrctl services# 服务在名单里,状态 READYsqlplus bizapp/Biz2024@192.168.1.10:1521/orcl# 直连串绕过 tnsnames 干扰sqlplus bizapp/Biz2024@orcl# 走 tnsnames 再验一遍

预防:

  • 开机脚本里,监听器启动之后、业务起来之前,加一句echo "alter system register;" | sqlplus -S / as sysdba(或在 startup 脚本末尾执行),抹掉空窗期
  • 改监听端口时同步改local_listener(第 10 篇的完整步骤已含这一步)
  • 新建实例后核对service_names与客户端连接串,写进交付文档
  • 对空窗敏感、需要远程拉库的环境,配好SID_LIST_LISTENER静态兜底
  • 巡检时把lsnrctl services的输出纳入例行检查项,服务数量和状态 READY 与历史基线对得上,注册类问题在爆发前就能看见

小结

  • 12514 = 监听器活着,但服务清单里没有你要的名字;先lsnrctl services看清单
  • 动态注册由实例自动完成(旧版 PMON 约每 60 秒一轮),alter system register;立即补一轮
  • 注册目标靠local_listener指路,非 1521 端口必查
  • SID_LIST_LISTENER静态注册是兜底:不依赖动态注册,代价是状态 UNKNOWN、不感知实例死活

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询