当前位置:首页 > 问答 > 正文

ORA-00118报错怎么解决,PROTOCOL和ADDRESS别同时写,远程连接出问题了咋办

ORA-00118这个错误,说白了就是数据库的监听配置文件(listener.ora)里写东西写“打架”了,根据Oracle官方文档(来源:Oracle Database Net Services Reference)和一些常见的DBA实践经验,这个错误的直接原因就是在配置监听程序的参数时,你把PROTOCOLADDRESS这两样东西同时写在了同一段配置里,让数据库监听程序“懵了”,不知道到底该听谁的。

错误的核心:别让监听器“选择困难”

你可以把数据库的监听器想象成一个公司的总机接线员,它的listener.ora文件就是它的工作手册,上面写着它应该在哪个IP地址、哪个端口号上接听电话(也就是客户端的连接请求)。

在这个手册里,有两种主要的写法来告诉接线员工作地点:

  1. 直接写死地址(使用ADDRESS参数):这就好比手册上明确写着“请你在192.168.1.100这台服务器的1521端口待命”,非常直接,没有歧义。
  2. 告诉它一个地址列表的名字(使用PROTOCOL参数):这就好比手册上写“请按照‘公司前台电话簿’这个列表里的第一个地址去待命”。PROTOCOL参数在这里指向的是另一个定义好的网络地址描述。

问题就出在,如果你在同一段配置里既写了ADDRESS=(具体地址),又写了PROTOCOL=某个描述,就相当于你对接线员说:“请你既在192.168.1.100的1521端口待命,同时又按照‘公司前台电话簿’的指示待命。” 接线员顿时就混乱了,只能报错“ORA-00118”,摆挑子不干了。

怎么解决:二选一,清理配置

解决办法非常简单粗暴:打开那个惹事的listener.ora文件(这个文件通常位于Oracle软件的安装目录下,比如$ORACLE_HOME/network/admin/),找到报错提示的那部分配置,看看是不是有类似下面的情况:

错误示范(会导致ORA-00118):

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = mydb)
      (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1)
      (PROTOCOL = TCP)        <-- 这里用了PROTOCOL
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.100)(PORT = 1521))  <-- 这里又用了ADDRESS
      (SID_NAME = mydb)
    )
  )

你需要做的是,在这两者之中只保留一个,根据你的实际需求,选择以下两种修改方式之一:

  • 保留ADDRESS,删除PROTOCOL(推荐,最常用) 直接把(PROTOCOL = TCP)这一行删掉,因为后面的ADDRESS里已经包含了PROTOCOL = TCP这个信息了,这是重复和多余的。

    SID_LIST_LISTENER =
      (SID_LIST =
        (SID_DESC =
          (GLOBAL_DBNAME = mydb)
          (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1)
          # (PROTOCOL = TCP)   <-- 把这一行注释掉或者直接删除
          (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.100)(PORT = 1521))
          (SID_NAME = mydb)
        )
      )
  • 保留PROTOCOL,删除整个ADDRESS(较少用) 如果你确实需要使用PROTOCOL指向的某种特定网络协议定义,那么就把整个ADDRESS那一行删掉,但这种用法相对复杂一些,对于解决大多数简单的远程连接问题,方案一更直接有效。

修改完配置文件后,切记要重启监听器服务,让新的配置生效。 在服务器上,使用命令行工具(如SQL*Plus或系统终端)执行:

lsnrctl stop   -- 停止监听器
lsnrctl start  -- 启动监听器

解决了ORA-00118,远程连接还不行怎么办?

解决了配置文件的语法错误,只是万里长征第一步,监听器能正常启动了,不代表远程连接就一定成功,如果此时你还是连不上数据库,别慌,我们可以按照“由内到外”的顺序一步步排查,这个过程就像侦探破案。

  1. 第一步:检查监听器本身是否“健康” 在数据库服务器上,再次运行lsnrctl status命令,这次重点看输出结果:

    • 监听器是否真的在RUNNING状态?
    • 在“服务摘要”部分,有没有列出你的数据库实例名(SID)和它的状态?理想状态应该是“READY”或“READY/SECONDARY”,如果显示为“UNKNOWN”,说明监听器还没能和数据库实例建立联系,问题可能出在数据库实例没启动,或者注册有问题。
  2. 第二步:检查数据库实例是否“在线” 在服务器上,连接到操作系统Oracle用户,使用sqlplus / as sysdba登录,然后执行select status from v$instance;,如果状态不是OPEN,说明数据库没打开,你需要启动它。

  3. 第三步:本地测试连通性(在服务器上自己连自己) 这是非常关键的一步,用来排除网络复杂性,在服务器上,使用Oracle自带的tnsping工具测试一下。

    tnsping 你的数据库网络服务名

    这个“网络服务名”对应的是客户端配置文件tnsnames.ora里的一个条目,如果tnsping能成功,显示“OK(XX毫秒)”,说明从服务器本地到监听器的网络路径是通的,监听器也是正常工作的,如果这里就失败了,说明问题还是出在服务器本地(监听器配置或网络服务名配置)。

  4. 第四步:检查防火墙 这是远程连接失败的“头号杀手”,确保客户端和服务器之间的1521端口(或你自定义的端口)是开放的。

    • 服务器防火墙:检查Linux的iptables/firewalld或Windows的防火墙规则,确保允许1521端口的入站连接。
    • 网络防火墙:如果客户端和服务器不在同一个局域网,中间可能还有公司或机房的硬件防火墙,需要联系网络管理员确认端口是否开放。
  5. 第五步:检查客户端的配置(tnsnames.ora) 问题可能根本不在服务器,而在你自己的电脑(客户端)上,打开客户端的tnsnames.ora文件,检查你连接时使用的那个服务名对应的配置是否正确,重点核对:

    • HOST= 后面写的是否是数据库服务器的正确IP地址(不是localhost也不是127.0.0.1)?
    • PORT= 后面写的是否是监听器实际监听的端口(默认1521)?
    • SERVICE_NAMESID 是否和服务器上的数据库一致?

ORA-00118是一个明确的配置语法错误,修正起来不难,难的是后续的远程连接排错,需要你耐心地、一步一步地检查监听器、数据库实例、本地连通性、防火墙和客户端配置这几个关键点,只要按照这个顺序排查,绝大多数远程连接问题都能找到根源。

ORA-00118报错怎么解决,PROTOCOL和ADDRESS别同时写,远程连接出问题了咋办