ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ORA-12560错误根因解析:Windows Server 2019下Oracle服务注册与监听器配置

ORA-12560错误根因解析:Windows Server 2019下Oracle服务注册与监听器配置

简介:本资源是一份面向数据库运维工程师、系统集成人员及Windows平台Oracle初学者的实战部署指南,聚焦Windows Server 2019环境下Oracle 11g与19c服务端及客户端的全流程安装配置。内容覆盖操作系统基础搭建(含Server 2019桌面体验版安装、磁盘分区管理)、Oracle 11.2.0.4服务端静默/图形化安装、19c Client连接配置(含典型连通性故障排查方案),并补充NIC网络聚合配置说明与PL/SQL工具连接实操要点,兼顾稳定性与兼容性验证。资源为单文件PDF文档,共1个5.13MB的图文详解手册,步骤截图丰富、操作路径清晰、关键选项标注明确,便于按图索骥完成生产级部署。目前已有1855人学习下载,适合需在新版本Windows Server上快速落地Oracle双版本环境的技术人员参考使用。

1. “ORA-12560: TNS: 协议适配器错误”——Windows Server 2019 上 Oracle 11g/19c 安装后连不上数据库,90% 的人卡在这一步

刚在 Windows Server 2019 上装完 Oracle 11g 或 19c,SQL*Plus 打开就报ORA-12560: TNS: protocol adapter error;PL/SQL Developer 点连接直接弹窗“无法初始化 Oracle 客户端”;tnsping 本地服务名返回TNS-03505: Failed to resolve name;甚至lsnrctl status都提示“服务未启动”或“找不到监听器”。这不是你操作错了,也不是下载包坏了——这是 Windows Server 2019 和 Oracle 双版本组合下最典型的「环境错位」:系统服务没注册、环境变量没生效、用户权限被绕过、Oracle 服务名与实例名不一致……全都是安装向导没告诉你、但实际运行时必须手动补全的“隐性契约”。尤其当你同时部署 11g(老旧但稳定)和 19c(新特性多但依赖严)时,两个版本对 .NET Framework、VC++ 运行库、UAC 权限、服务账户类型的要求完全不同,稍有偏差就触发连锁失败。这篇笔记不讲“怎么点下一步”,只聚焦你截图发到技术群后别人问“你服务启了吗?tnsnames.ora 放哪了?ORACLE_HOME 设对没?”时,你真正需要的答案——从报错现象反推根因,用命令验证每一步,把安装文档里省略的“血泪经验”变成可执行 checklist。适合正在部署 PACS、HIS、ERP 等传统行业系统的运维工程师、DBA,以及接手遗留项目的开发同学。


2. ORA-12560 根因拆解:不是监听器没起,而是 Oracle 服务根本没注册进 Windows 服务管理器

这个报错表面是网络层问题,实则是 Windows 服务层断链。Oracle 在 Windows 下不靠 systemd 或 launchd,而是依赖 Windows Service Control Manager(SCM)。一旦数据库软件安装完成但未成功注册为 Windows 服务,哪怕监听器进程(tnslsnr.exe)手动跑起来了,sqlplus / as sysdba也会因找不到默认实例而抛出 ORA-12560。尤其在 Server 2019 中,UAC 默认启用、服务账户策略收紧、PowerShell 执行策略限制更严,导致oradim创建服务时静默失败——安装日志里可能只有一行INFO: Creating service...,但 SCM 中查无此服务。

2.1 验证 Oracle 服务是否真实存在

先别急着重装,打开管理员权限的 PowerShell,执行:

Get-Service | Where-Object {$_.Name -like "OracleService*"} | Format-Table Name, Status, StartType

提示:必须用管理员权限运行。普通用户 PowerShell 无法读取服务状态,会返回空结果,误导你认为“服务不存在”。

如果输出为空,说明oradim创建服务失败;如果存在但Status是Stopped,则需进一步检查启动失败原因(见 2.3 节);如果StartType是Disabled,说明安装时被 UAC 或组策略拦截。

2.2 手动创建 Oracle 服务(适用于 11g 和 19c)

当Get-Service查不到服务时,不能直接双击 setup.exe 重装——那只会覆盖已配置的 ORACLE_HOME。正确做法是进入 Oracle 软件安装目录下的bin子目录,用oradim工具重建服务。以典型路径为例(请按你实际路径调整):

cd C:\app\oracle\product\11.2.0\dbhome_1\BIN oradim -NEW -SID orcl -STARTMODE manual -SPFILE
cd C:\app\oracle\product\19c\dbhome_1\BIN oradim -NEW -SID ORCLCDB -STARTMODE auto -SPFILE
  • -SID:必须与你安装时指定的数据库 SID 完全一致(区分大小写!19c 默认是ORCLCDB,11g 默认是ORCL),可通过查看C:\app\oracle\product\*\dbhome_*\database\init<SID>.ora文件确认;
  • -STARTMODE manual/auto:manual表示需手动启动(适合调试),auto表示开机自启(生产环境推荐);
  • -SPFILE:强制使用服务器参数文件(spfile),避免pfile路径错误导致实例无法加载。

执行后再次运行Get-Service | Where-Object {$_.Name -like "OracleService*"},应看到OracleServiceORCL或OracleServiceORCLCDB出现,且Status为Stopped。

2.3 启动服务失败的深层排查:事件查看器是你的黑匣子

即使服务创建成功,Start-Service OracleServiceORCL仍可能报错:“服务未及时响应控制请求”。此时不要反复重启,打开 Windows 事件查看器 → Windows 日志 → 应用程序,筛选来源为OracleService或Oracle的错误事件。常见三类日志:

事件 ID错误描述根因解决方案
100ORA-01078: failure in processing system parametersspfile 损坏或路径错误检查C:\app\oracle\product\11.2.0\dbhome_1\database\spfileORCL.ora是否存在;若不存在,用CREATE SPFILE FROM PFILE;重建
101ORA-00845: MEMORY_TARGET not supported on this systemServer 2019 默认禁用大页(Large Page),而 19c 的MEMORY_TARGET依赖它修改spfile,将memory_target=0,改用sga_target+pga_aggregate_target手动分配
102ORA-12638: Credential retrieval failedWindows 身份验证模式下 Kerberos 票据获取失败临时改用SQLNET.AUTHENTICATION_SERVICES=(NTS),或在域环境中配置 SPN

注意:19c 在 Server 2019 上默认启用SEC_CASE_SENSITIVE_LOGON=TRUE,若你用sqlplus / as sysdba失败,先确认当前登录用户是否属于ORA_DBA本地组(见 3.2 节)。


3. 监听器启动失败:tnslsnr.exe 报错“TNS-01106: 使用字符串...的监听器已经启动”,但 lsnrctl status 无响应

这是另一个高频幻觉:你以为监听器起来了,其实只是进程残留或端口冲突。tnslsnr.exe是单实例进程,同一端口(默认 1521)只能有一个监听器绑定。Server 2019 的 Hyper-V、WSL2、Docker Desktop 默认占用 1521 端口,导致 Oracle 监听器启动时“伪成功”——lsnrctl start返回The command completed successfully,但lsnrctl status却显示Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))后卡住,或直接报TNS-12541: TNS:no listener。

3.1 确认端口真实占用情况

在管理员 PowerShell 中执行:

netstat -ano | findstr :1521

若输出类似:

TCP 0.0.0.0:1521 0.0.0.0:0 LISTENING 4567 TCP [::]:1521 [::]:0 LISTENING 4567

则 PID4567正在占用 1521。用以下命令查进程名:

Get-Process -Id 4567 | Format-List ProcessName, Path
  • 若是vmms.exe(Hyper-V)、wslhost.exe(WSL2)或com.docker.backend.exe(Docker),需停用对应服务;
  • 若是tnslsnr.exe但 PID 不同,则说明旧监听器未正常关闭,需taskkill /f /pid 4567强杀。

3.2 重置监听器配置:删掉所有自动生成的冗余文件

Oracle 安装向导常在%ORACLE_HOME%\network\admin\下生成多个listener.ora副本(如listener.ora.bak,listener.ora.old),而lsnrctl会优先读取第一个匹配文件,导致配置混乱。安全做法是彻底清空该目录,只保留一个干净的listener.ora:

cd %ORACLE_HOME%\network\admin del /f /q listener.ora* del /f /q tnsnames.ora*

然后用netca(Network Configuration Assistant)图形化工具重建监听器(推荐),或手写最小化配置:

# %ORACLE_HOME%\network\admin\listener.ora LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) ) ) ADR_BASE_LISTENER = C:\app\oracle

逻辑说明:HOST = localhost强制监听本地回环,避免 Server 2019 的 NIC 聚合(见摘要第2点)导致 IP 绑定失败;ADR_BASE指定诊断日志路径,防止因权限问题写入失败。

3.3 验证监听器是否真正在工作:绕过 tnsnames.ora 直连

tnsping依赖tnsnames.ora,而tnsnames.ora又常因格式错误(多余空格、中文标点、括号不匹配)失效。最可靠的验证方式是用 Easy Connect 语法直连:

sqlplus system/oracle@localhost:1521/ORCLCDB
  • 若成功登录,说明监听器和数据库实例均正常,问题出在tnsnames.ora配置;
  • 若报ORA-12154: TNS:could not resolve the connect identifier specified,说明监听器未监听该服务名,需检查listener.ora中SID_LIST_LISTENER是否包含对应SID_DESC(11g 必须显式配置,19c 可自动注册);
  • 若报ORA-12541: TNS:no listener,说明lsnrctl start未真正生效,回到 3.1 节查端口。

4. Oracle 19c Client 连接失败:PL/SQL Developer 报“Initialization error”,tnsping 返回 TNS-03505

摘要中明确提到“Oracle 19c Client 数据源连接详解”,这恰恰是 Server 2019 环境下最易被忽略的兼容性断点。19c Client 默认要求 TLS 1.2+ 加密协议,而 Server 2019 的 .NET Framework 4.8 默认禁用弱加密套件,但某些旧版 PL/SQL Developer(如 v12.0.7)仍尝试用 SSLv3 握手,导致连接被服务端拒绝。更隐蔽的是,19c Client 安装包自带的oraociei19.dll与 Server 2019 的ucrtbase.dll(Universal CRT)版本不匹配,引发 DLL 加载失败。

4.1 强制客户端降级加密协议(临时方案)

在客户端机器的%ORACLE_HOME%\network\admin\sqlnet.ora中添加:

SQLNET.ENCRYPTION_SERVER = rejected SQLNET.CRYPTO_CHECKSUM_SERVER = rejected SSL_VERSION = 1.0

参数说明:rejected表示“不强制要求”,允许服务端协商;SSL_VERSION = 1.0实际启用 TLS 1.0(非 SSLv3),这是 Server 2019 仍支持的最低安全级别,能绕过握手失败。生产环境上线前必须改回required并升级客户端。

4.2 修复 DLL 依赖:用 Dependency Walker 定位缺失模块

下载 Dependency Walker(depends.exe),打开%ORACLE_HOME%\BIN\oraociei19.dll,观察右侧依赖列表。若出现ucrtbase.dll标红(红色图标),说明系统缺少 Universal CRT。Server 2019 自带该 DLL,但路径不在 Oracle 的 DLL 搜索路径中。解决方法是将C:\Windows\System32添加到系统 PATH(需重启 CMD 生效),或复制ucrtbase.dll到%ORACLE_HOME%\BIN\目录下(不推荐,污染 Oracle 目录)。

4.3 PL/SQL Developer 配置要点:别信“自动检测”

PL/SQL Developer 的“Database” → “Configure” → “Connection” 中,“Oracle Home” 必须指向 19c Client 的完整路径(如C:\app\client\oracle\product\19c\client_1),而非C:\app\client\oracle\product\19c;“OCI Library” 必须指定为%ORACLE_HOME%\BIN\oci.dll(注意是oci.dll,不是oraociei19.dll)。若勾选“Auto detect”,它会扫描注册表找第一个 Oracle Home,极大概率选中 11g 的路径,导致 19c 连接失败。

避坑 / 常见问题 / 排查

4.4 五条血泪踩坑记录(现象 → 原因 → 解决)

  • 现象:PL/SQL Developer 连接时弹窗“Initialization error: OCI.DLL not found”,但oci.dll明明在%ORACLE_HOME%\BIN\下。
    原因:Windows 的 DLL 加载顺序中,当前目录(PL/SQL 安装目录)优先级高于PATH,而该目录下存在旧版oci.dll(如 10g 版本)。
    解决:删除 PL/SQL 安装目录下的oci.dll,或在 PL/SQL 的“Preferences” → “Oracle” → “Connection” 中取消勾选 “Use OCI library from Oracle Home only”。

  • 现象:tnsping ORCL成功,但sqlplus system/oracle@ORCL报ORA-12170: TNS:Connect timeout occurred。
    原因:Server 2019 的 Windows Defender 防火墙默认阻止tnslsnr.exe入站连接,即使监听器在本地运行。
    解决:运行New-NetFirewallRule -DisplayName "Oracle Listener" -Direction Inbound -Program "%ORACLE_HOME%\BIN\tnslsnr.exe" -Action Allow -Enabled True。

  • 现象:19c Client 安装后,sqlplus命令在 CMD 中可用,但在 PowerShell 中输入sqlplus提示“不是内部或外部命令”。
    原因:PowerShell 默认不继承 CMD 的PATH环境变量,且ORACLE_HOME在 PowerShell 中未设为全局变量。
    解决:在 PowerShell 中执行$env:ORACLE_HOME="C:\app\client\oracle\product\19c\client_1",并运行[Environment]::SetEnvironmentVariable("ORACLE_HOME", $env:ORACLE_HOME, "Machine")永久生效。

  • 现象:NIC 网络聚合后,tnsping用服务器 IP 能通,但用主机名(如myserver.domain.local)报TNS-03505。
    原因:聚合网卡的 DNS 注册被禁用,nslookup myserver返回空,导致 Oracle 解析主机名失败。
    解决:在“服务器管理器” → “本地服务器” → “NIC 聚合” → 右键聚合接口 → “属性” → “Internet 协议版本 4 (TCP/IPv4)” → “属性” → “高级” → “DNS” → 勾选 “在 DNS 中注册此连接的地址”。

  • 现象:11g 和 19c Client 共存时,sqlplus总调用 11g 的oci.dll,导致 19c 数据库连接报ORA-28040: No matching authentication protocol。
    原因:Windows 的PATH环境变量中,11g 的BIN目录排在 19c 前面,系统优先加载前者。
    解决:编辑系统环境变量,将 19c Client 的BIN路径(如C:\app\client\oracle\product\19c\client_1\BIN)移到PATH最前面,并确保ORACLE_HOME指向 19c 路径。


5. 快速定位:一套命令走完,3 分钟判断是环境、配置还是权限问题

面对ORA-12560、TNS-12541、ORA-12170这类“万能报错”,我从不逐个试配置。而是用一套固定顺序的验证命令,像流水线一样过滤根因。这套流程来自某跨平台系统部署中连续 7 次翻车后的后悔药,现在已成为我每次 Oracle 安装后的强制动作。

5.1 第一层:确认 Windows 服务与进程状态(10 秒)

# 1. 查 Oracle 服务是否存在且可启动 Get-Service OracleService* -ErrorAction SilentlyContinue | Select-Object Name, Status, StartType # 2. 查 tnslsnr 进程是否在运行(不依赖服务状态) Get-Process tnslsnr -ErrorAction SilentlyContinue | Select-Object Id, Path # 3. 查 1521 端口是否被监听(最真实的状态) netstat -ano | findstr :1521
  • 若服务不存在 → 回到 2.2 节手动oradim;
  • 若进程存在但端口未监听 → 说明tnslsnr.exe是僵尸进程,taskkill /f /im tnslsnr.exe后重启;
  • 若端口被其他 PID 占用 → 执行Get-Process -Id <PID>定位并停用。

5.2 第二层:绕过所有配置文件,直连验证(30 秒)

# 用 Easy Connect 语法,不读 tnsnames.ora,不走监听器别名 sqlplus /nolog SQL> connect system/oracle@localhost:1521/ORCLCDB
  • 若成功 → 问题 100% 出在tnsnames.ora或sqlnet.ora配置,跳到 5.3;
  • 若报ORA-12541→ 监听器未启动或未监听该端口,回到 3.1;
  • 若报ORA-12170→ 防火墙或网络层阻断,检查 4.4 第二条;
  • 若报ORA-01017(用户名密码错误)→ 数据库实例已启动,连接通路正常,问题在认证。

5.3 第三层:配置文件语法与路径审计(2 分钟)

Oracle 对配置文件格式极其敏感。我写了个 PowerShell 脚本自动检查tnsnames.ora和listener.ora:

function Test-OracleConfig { param($Path) if (-not (Test-Path $Path)) { Write-Host "$Path not found"; return } $content = Get-Content $Path -Raw # 检查括号匹配 $open = ($content | Select-String -Pattern "\(" -AllMatches).Matches.Count $close = ($content | Select-String -Pattern "\)" -AllMatches).Matches.Count if ($open -ne $close) { Write-Host "$Path: bracket mismatch ($open vs $close)" } # 检查中文字符(常见粘贴错误) if ($content -match "[\u4e00-\u9fff]") { Write-Host "$Path: contains Chinese characters" } # 检查路径是否存在(针对 DIRECTORY=... 类配置) $dirs = ($content | Select-String -Pattern "DIRECTORY=.*?" -AllMatches).Matches | ForEach-Object { $_.Value.Split('=')[1].Trim('"') } foreach ($dir in $dirs) { if (-not (Test-Path $dir)) { Write-Host "$Path: directory $dir not exists" } } } Test-OracleConfig "$env:ORACLE_HOME\network\admin\tnsnames.ora" Test-OracleConfig "$env:ORACLE_HOME\network\admin\listener.ora"

运行后,脚本会直接告诉你哪一行有中文、哪个括号没闭合、哪个目录路径不存在——比肉眼扫 200 行配置快 10 倍。

5.4 第四层:权限与组成员关系终审(30 秒)

最后也是最容易被忽略的一环:Windows 本地组权限。Oracle 在 Windows 下的SYSDBA认证依赖ORA_DBA本地组。Server 2019 默认不将 Administrator 加入该组,导致sqlplus / as sysdba失败。

# 查当前用户是否在 ORA_DBA 组 $currentUser = whoami net user $currentUser | findstr "ORA_DBA" # 若无输出,手动添加(需管理员权限) net localgroup ORA_DBA $currentUser /add

从那以后我每次在 Server 2019 上装完 Oracle,不管装的是 11g 还是 19c,都强制走一遍这四步命令:服务→直连→配置→权限。少一次,就多一次凌晨三点对着黑窗口发呆。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进