# iPaaS启动或者运行时数据库连接失败问题
# 问题1、Oracle数据库连接失败 (ORA-12505):TNS:listener does not currently know of SID given in connect descriptor
# 问题现象
ESBServer启动,服务器后台报错,druid数据源在创建数据库连接时抛出java.sql.SQLException,具体错误信息为:ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
连接URL为:jdbc:oracle:thin:@192.168.xx.xx:1521:orcl
# 错误原因分析
# 核心错误解读
ORA-12505 是Oracle数据库的典型连接错误,字面意思是:"监听器当前不知道连接描述符中给出的SID"。
# 具体原因
根据错误堆栈和连接URL分析,可能的原因包括:
SID/服务名称不匹配
- 连接串中指定的SID为
orcl,但Oracle监听器中配置的SID名称可能不同 - 可能是SID写错,或者实际SID是区分大小写的(虽然通常不区分)
- 可能实际使用的是Service Name而非SID,但连接串中使用了SID格式
- 连接串中指定的SID为
监听器未注册目标实例
- Oracle监听器(Listener)没有正确注册该SID对应的数据库实例
- 数据库服务可能未启动或未注册到监听器
监听器配置问题
listener.ora文件中可能没有配置orcl这个SID- 或者配置了静态监听但SID名称不匹配
数据库实例状态异常
- 数据库实例虽然存在,但可能处于
MOUNTED而非OPEN状态 - 或者数据库服务未正常启动
- 数据库实例虽然存在,但可能处于
# 解决方案
# 第一步:确认SID/Service Name的正确性
在数据库服务器上执行以下命令,查看正确的SID和Service Name:
-- 查看数据库名称(通常就是SID)
SELECT name FROM v$database;
-- 查看服务名称
SELECT value FROM v$parameter WHERE name = 'service_names';
-- 查看监听器状态(操作系统命令)
lsnrctl status
# 第二步:修正连接URL
根据确认的信息,修正连接URL:
情况A:如果使用SID连接
jdbc:oracle:thin:@192.168.78.169:1521:正确的SID
情况B:如果使用Service Name连接
jdbc:oracle:thin:@192.168.78.169:1521/正确的ServiceName
# 第三步:验证连接性
使用Oracle客户端工具测试连接:
sqlplus 用户名/密码@192.168.78.169:1521/实际SID
# 经验总结
# 根本原因
本次错误ORA-12505的根本原因是连接字符串中指定的SID与Oracle监听器中实际配置的SID不一致。数据库监听器接收到连接请求后,在自身的SID列表中找不到请求的orcl,因此拒绝连接。
区分SID和Service Name
- 注意JDBC URL中SID使用冒号
:,Service Name使用斜杠/ - 如:
jdbc:oracle:thin:@host:port:SIDvsjdbc:oracle:thin:@host:port/ServiceName
# 排查思路总结
遇到类似连接问题时,排查路径应为:
- 检查网络连通性:
telnet IP 1521 - 验证监听器状态:
lsnrctl status - 确认SID/Service Name:对比连接串与监听器配置
- 检查数据库状态:实例是否OPEN
- 验证防火墙/SELinux:是否阻止连接
# 问题2、密码过期导致 IPaaS 连接失败
# 问题现象
- 环境描述:存在一个 Oracle 数据库源。
- 故障现象:IPaaS 平台启动时持续报错,无法连接到数据库。后台错误日志显示“ORA-01017: 用户名/口令无效; 登录被拒绝”。
- 对比测试:使用相同的用户名和密码,通过 PLSQL Developer 等客户端工具可以正常登录并访问数据库。
# 问题分析
这是一个典型的因数据库密码状态导致不同客户端连接行为不一致的案例。核心原因在于 Oracle 的用户密码已过期,但处于宽限期(Grace Period)内。
# Oracle 密码过期机制与宽限期
Oracle 数据库为了安全性,可以设置密码过期策略。当用户的密码使用时间超过设定的生命周期(由 PASSWORD_LIFE_TIME 参数控制)时,密码状态会变为 EXPIRED(GRACE)。
- 宽限期:在密码刚过期的这段时间内,Oracle 允许用户继续登录,但每次登录都会收到一个“密码即将过期”的警告。在这个阶段,用户依然可以正常执行 SQL 语句。
- 设计目的:为了提醒用户更改密码,但不会中断业务,给应用程序和用户一个缓冲时间。
# 为何连接表现不一致?
这种“宽限期内允许登录”的行为依赖于客户端的实现方式。
- PLSQL Developer 等客户端:这类工具通常使用 OCI (Oracle Call Interface) 驱动连接数据库。OCI 驱动对 Oracle 的错误和警告处理得比较完善。当收到数据库返回的“密码已过期”警告时,OCI 驱动会识别这只是警告,并继续完成登录流程,因此连接成功。
- IPaaS 平台:IPaaS 平台通常使用 JDBC (Java Database Connectivity) 驱动连接数据库。某些版本或特定配置下的 JDBC 驱动,对数据库返回的错误码处理可能更为严格。当它接收到数据库返回的 ORA-28001(密码已过期)错误信息时,会将其直接判断为致命错误(即“口令无效”),并抛出
ORA-01017异常,从而导致连接被拒绝。
# 关键结论
用户的密码已过期,但处于宽限期内的状态,是导致 IPaaS 连接失败的根源。 即使宽限期内可以执行查询,JDBC 驱动的严格校验机制也会阻止连接的建立。
# 解决方案
根本解决方案:重置用户密码,解除过期状态。
一旦密码被重置,用户的密码状态将从 EXPIRED(GRACE) 变回正常的 OPEN 状态。此后,无论是 OCI 驱动还是 JDBC 驱动,都能正常建立连接。
# 操作步骤(使用 DBA 或具有相应权限的用户执行)
登录数据库: 使用具有 DBA 权限的账户(如
system)通过 SQL*Plus 或 SQL 开发工具登录到数据库。重置密码: 执行以下 SQL 语句,将问题用户的密码重置(可以设置为原密码或新密码)。
-- 将 <username> 替换为实际的用户名,<password> 替换为密码 ALTER USER <username> IDENTIFIED BY <password>;例如:将
app_user用户的密码重置为oracle123ALTER USER app_user IDENTIFIED BY oracle123;(可选)检查账户状态: 执行以下查询,确认用户状态已变为
OPEN。SELECT username, account_status, expiry_date FROM dba_users WHERE username = 'APP_USER'; -- 注意用户名大写
- 期望结果:
account_status字段应为OPEN。
```
# 总结
| 现象 | IPaaS 报错“用户名/口令无效”,PLSQL 连接正常 |
|---|---|
| 根本原因 | Oracle 用户密码已过期,但处于宽限期内。JDBC 驱动将过期警告视为致命错误,而 OCI 驱动(PLSQL)仅作为警告处理。 |
| 解决方案 | 使用 ALTER USER ... IDENTIFIED BY ... 命令重置密码,解除过期状态。 |
| 核心要点 | 不要被“PLSQL 能连”的表象迷惑。密码过期状态对于不同驱动的连接行为影响巨大。当遇到此类连接不一致问题时,应优先检查数据库用户的 account_status 和 expiry_date。 |
# 问题3:Portal启动慢且无法连接数据库问题排查
# 问题现象
- Portal 启动过程非常缓慢。
- 最终启动失败,后台报错:
Message: cannot found datasource with name 'default' .(the datasource with name default cannot get connection(无法找到名为 'default' 的数据源,该数据源无法获取连接)。
# 问题分析
这是一个由于操作系统主机名解析问题导致达梦 JDBC 驱动初始化失败的案例。核心原因在于 系统 hostname 未正确配置在 /etc/hosts 文件中。
# 达梦 JDBC 驱动的初始化机制
达梦数据库的 JDBC 驱动在初始化连接池或获取连接时,会尝试获取本地主机的主机名(hostname)进行某些校验或注册操作。这个过程依赖于操作系统能够正确地将主机名解析为 IP 地址。
# 主机名解析失败的原因
- 获取主机名:操作系统通过
hostname命令获取到的主机名为api--0001.novalocal。 - 解析失败:JDBC 驱动尝试解析这个主机名时,系统会检查
/etc/hosts文件和 DNS 配置。但在/etc/hosts文件中,只配置了默认的 localhost 解析,没有包含api--0001.novalocal的任何解析记录。# 原 /etc/hosts 内容(缺失主机名映射) 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 - 解析超时:由于无法解析主机名,JDBC 驱动可能会尝试其他解析方式(如 DNS 查询),这个过程会产生超时等待,直接导致 Portal 启动变慢。
- 初始化失败:主机名解析失败最终导致 JDBC 驱动初始化过程中的某个关键步骤无法完成,使得连接池无法正常创建和获取连接,从而抛出
cannot get connection的错误。
# 解决方案
根本解决方案:在 /etc/hosts 文件中添加主机名的解析记录。
# 操作步骤
确认当前主机名: 在服务器上执行以下命令,获取当前系统的主机名。
hostname确认输出为:
api--0001.novalocal备份原 hosts 文件(安全起见):
cp /etc/hosts /etc/hosts.bak编辑 /etc/hosts 文件: 使用 vi 或 vim 编辑器打开 hosts 文件。
vi /etc/hosts添加主机名映射: 在原有的 localhost 条目后,添加主机名
api--0001.novalocal。建议同时配置 IPv4 和 IPv6 的回环地址映射。# 修改后的 /etc/hosts 内容 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 api--0001.novalocal ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 api--0001.novalocal(可选)配置实际 IP 映射: 如果服务器配置了实际 IP 地址,建议也将实际 IP 与主机名进行映射(将
x.x.x.x替换为服务器的实际内网或公网 IP)。# 添加实际 IP 映射 x.x.x.x api--0001.novalocal保存文件并退出。
重启 Portal 服务: 完成 hosts 文件修改后,重新启动 Portal 服务。
验证结果:
- 观察 Portal 启动速度是否恢复正常。
- 检查日志,确认不再报
cannot found datasource错误。 - 确认 Portal 成功连接到达梦数据库。
# 总结
| 现象 | Governor 启动慢,报错 cannot found datasource with name 'default' |
|---|---|
| 根本原因 | 达梦 JDBC 驱动初始化时需要解析本地主机名 api--0001.novalocal,但 /etc/hosts 文件中缺少该主机名的映射,导致解析失败和超时。 |
| 解决方案 | 在 /etc/hosts 文件中添加主机名 api--0001.novalocal 到 127.0.0.1 和 ::1 的映射(及实际 IP 映射)。 |
| 核心要点 | 数据库驱动(特别是达梦、Oracle 等)在初始化时可能依赖主机名的正确解析。当遇到启动慢或连接超时类问题时,应检查操作系统的 hosts 配置和主机名解析是否正常。 |