Oracle 11g 透明网关连接 SQL Server
从安装配置到 ORA-28513 / ORA-28500 的分层排障实战
Oracle 客户端经 Oracle Server、Database Gateway 访问 SQL Server
基于 Oracle Database Gateway for Microsoft SQL Server 11.2.0.4(Windows)
更新日期:2026-07-30
摘要|本文在原有 Oracle 11g 透明网关安装笔记基础上,补充一次真实故障复盘:最初查询报 ORA-28513,修正 Gateway SID 与连接串后错误推进为 ORA-28500,从而确认代理已经正常、剩余问题位于 SQL Server 端口或网络层。全文给出可复用配置模板、验证顺序和错误码判断方法。
1. 为什么还要写这篇文章
Oracle Database Gateway 的配置文件不多,但每个名字都必须彼此对应;同时,一条数据库链路跨越 Oracle 数据库、Oracle Net Listener、Gateway Agent、SQL Server 网络协议和远端对象五个层次。只看最终 SQL 报错,很容易在错误层级反复修改。
这次排障最重要的经验不是某一行参数,而是建立“错误推进”的意识:当 ORA-28513 变成带有 ODBC 原生信息的 ORA-28500 时,说明故障已经从代理初始化层推进到了 SQL Server 网络层。错误变化本身就是定位证据。
结论先行|先用 DUAL@dblink 验证基础链路,再查业务视图;先看错误来自哪一层,再改对应配置。不要因为 DB Link 查询失败就反复删除、重建 DB Link。
2. 架构与组件职责
| 组件 | 所在位置 | 职责 |
|---|---|---|
| Oracle Database | Oracle 服务器 | 解析 SQL,通过 TNS 别名连接 Gateway,并维护 Database Link。 |
| Gateway Listener | Windows Gateway 主机 | 监听 Oracle Net 请求,按静态 SID 启动 dg4msql.exe。 |
| dg4msql Agent | Gateway Home | 登录 SQL Server、翻译 SQL 与数据类型,并将结果返回 Oracle。 |
| SQL Server | 远端数据库服务器 | 在业务 TCP 端口接受连接并执行查询。 |
两个端口不要混淆|Gateway Listener 端口(示例 1521)供 Oracle 连接 Gateway;SQL Server 端口(示例 1433/1443)供 Gateway 连接 SQL Server。它们属于不同链路。
3. 环境与前置条件
| 项目 | 示例值 | 说明 |
|---|---|---|
| Oracle 数据库 | 11.2.0.4 | 数据库端可运行在 Linux 或 Windows。 |
| Gateway | 11.2.0.4 x64 | 安装在能访问 SQL Server 的 Windows 主机。 |
| SQL Server | 2008 / 兼容版本 | 本文原始环境为 SQL Server 2008;新版本需核对认证矩阵。 |
| Gateway 程序 | dg4msql | 专用 Microsoft SQL Server Gateway,不是通用 dg4odbc。 |
| 示例 TNS 别名 | TIJIAN | Oracle 端使用的连接别名。 |
| 示例 Gateway SID | MSSQLGW | 同时出现在 init 文件名、listener.ora 和 tnsnames.ora。 |
确认 Gateway 主机可以解析或访问 SQL Server 主机名/IP。
确认 SQL Server 已启用 TCP/IP,并明确静态端口或实例名。
确认 Gateway 与 SQL Server 的位数、驱动和支持版本符合部署要求。
正式发布前,将真实 IP、账号和密码替换为安全配置,不在博客或工单中暴露明文凭据。
4. 下载与安装 Oracle Database Gateways
Oracle Database 11.2.0.4 Windows x64 补丁集 13390677 被拆分为 7 个压缩包,其中 Gateway 对应第 5 个包:
p13390677_112040_MSWIN-x86-64_5of7.zip解压后运行 setup.exe,在产品组件中选择 Oracle Database Gateway for Microsoft SQL Server。建议安装到独立 Oracle Home,例如:
D:\product\11.2.0\tg_1原文历史截图:在安装器中选择 Oracle Database Gateway for Microsoft SQL Server
安装器会询问 SQL Server 主机、实例和数据库;最终仍应核对生成的 init<SID>.ora
版本提示|11g 已属于遗留版本。若目标 SQL Server 或 Windows 版本较新,应优先查 Oracle 认证矩阵、补丁要求和支持策略;不要仅凭“能够安装”判断“受支持”。
5. 三份配置必须形成同一个命名闭环
本例统一使用 Gateway SID=MSSQLGW。下列三处必须一致,否则 Agent 可能找不到正确初始化文件,或启动错误的 Gateway 实例。
| 位置 | 必须出现的值 | 示例 |
|---|---|---|
| dg4msql\admin | 初始化文件名 | initMSSQLGW.ora |
| listener.ora | SID_NAME | MSSQLGW |
| tnsnames.ora | CONNECT_DATA / SID | MSSQLGW |
5.1 配置 init<SID>.ora
文件路径示例:D:\product\11.2.0\tg_1\dg4msql\admin\initMSSQLGW.ora
# 显式端口,省略实例名 HS_FDS_CONNECT_INFO=192.0.2.20:1443//HISDB # 排障阶段开启,稳定后改回 OFF HS_FDS_TRACE_LEVEL=DEBUG # 生产环境不要使用示例弱口令 HS_FDS_RECOVERY_ACCOUNT=GW_RECOVER HS_FDS_RECOVERY_PWD=<STRONG_PASSWORD>三种常见连接形式:
| 场景 | 写法 | 注意事项 |
|---|---|---|
| 指定端口,省略实例 | host:port//database | 端口与实例名不要同时填写。 |
| 指定命名实例 | host/instance/database | 依赖实例解析/SQL Server Browser。 |
| 默认实例与默认端口 | host//database | 确认服务实际监听 1433。 |
本次踩坑|错误写法将逗号端口、默认实例 MSSQLSERVER 和数据库名混在一起。修正为 host:port//database 后,错误从 ORA-28513 变成 ORA-28500 Connection refused,证明 Gateway 已能正确解析连接串并尝试访问目标端口。
5.2 配置 Gateway 的 listener.ora
LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.0.2.10)(PORT = 1521)) (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) ) SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = MSSQLGW) (ORACLE_HOME = D:\product\11.2.0\tg_1) (PROGRAM = dg4msql) ) )PROGRAM=dg4msql 表示使用专用 SQL Server Gateway。静态注册的 Gateway 服务在 lsnrctl services 中显示 status UNKNOWN 通常是正常现象,并不表示服务异常。
5.3 配置 Oracle 数据库端 tnsnames.ora
TIJIAN = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP) (HOST = 192.0.2.10) (PORT = 1521) ) (CONNECT_DATA = (SID = MSSQLGW) ) (HS = OK) )关键参数|(HS=OK) 告诉 Oracle Net:目标是异构服务,而不是普通 Oracle 数据库实例。
6. 重启并验证 Gateway Listener
务必使用 Gateway Home 自己的 lsnrctl,避免误操作数据库 Oracle Home 下的监听器:
D:\product\11.2.0\tg_1\bin\lsnrctl stop LISTENER D:\product\11.2.0\tg_1\bin\lsnrctlstartLISTENER D:\product\11.2.0\tg_1\bin\lsnrctl services LISTENER预期看到类似输出:
Service "MSSQLGW" has 1 instance(s). Instance "MSSQLGW", status UNKNOWN, has 1 handler(s) for this service...原文历史截图:Gateway 静态服务显示 UNKNOWN,但 Listener 已识别该 SID
7. 创建 Database Link:先查再建
PUBLIC Database Link 不会出现在 USER_DB_LINKS 中。本次排障中,USER_DB_LINKS 返回 no rows selected,但再次创建同名 public link 却报 ORA-02011,原因就是现有链接属于 PUBLIC。
查询当前用户可见的公有/私有 Database Link
SELECTowner,db_link,username,hostFROMall_db_linksWHEREUPPER(db_link)LIKE'TIJIAN%';确认不存在同名链接后再创建
CREATEPUBLICDATABASELINK tijianCONNECTTOnetstar IDENTIFIEDBY"<PASSWORD>"USING'TIJIAN';安全提示|不要把真实密码粘贴到博客、聊天或截图中。PUBLIC Database Link 对数据库中所有用户可见,应使用最小权限 SQL Server 账号,并在凭据暴露后立即轮换。
8. 正确的验证顺序
验证 TNS 能定位 Gateway Listener:tnsping TIJIAN。
验证 Listener 已识别静态 Gateway SID:lsnrctl services LISTENER。
验证 Gateway 能建立最小远端会话:SELECT * FROM dual@tijian。
基础链路成功后,再验证简单实体表与 schema 限定名。
最后再查询复杂视图,并逐列排查不兼容数据类型。
-- 1. 最小链路测试SELECT*FROMdual@tijian;-- 2. schema 限定的简单对象SELECTCOUNT(*)FROM"dbo"."SIMPLE_TABLE"@tijian;-- 3. 最后测试业务视图SELECTCOUNT(*)FROM"dbo"."V_REGLISREQUEST"@tijian;为什么先测 DUAL|如果 DUAL 都失败,问题与业务视图、字段类型和 schema 无关;继续拆视图没有意义。Oracle 官方配置指南也使用 SELECT * FROM DUAL@dblink 验证 Gateway。
9. 本次故障复盘:错误如何一步步变得更具体
| 阶段 | 现象 | 证据与结论 | 下一步 |
|---|---|---|---|
| 1 | ORA-28513 + ORA-02063 | Gateway Agent 内部失败;业务视图、COUNT(*)、空结果查询均失败。 | 停止查视图,改测 DUAL;开启 DEBUG trace。 |
| 2 | USER_DB_LINKS 无记录,但创建报 ORA-02011 | 现有链接为 PUBLIC,不是链接缺失。 | 改查 ALL_DB_LINKS/DBA_DB_LINKS。 |
| 3 | DUAL@TIJIAN 仍报 ORA-28513 | 确认与业务对象无关,故障在 Gateway 初始化/连接阶段。 | 核对 SID、init 文件名、listener、tnsnames。 |
| 4 | 修正连接串后变为 ORA-28500 Connection refused | dg4msql 已正常启动并调用 SQL Server Wire Protocol;目标端口拒绝连接。 | 检查 SQL Server TCP 端口、服务和防火墙。 |
9.1 ORA-28513:代理层错误
ORA-28513: internal error in heterogeneous remote agent ORA-02063: preceding line from TIJIANORA-28513 本身很泛,不能直接说明是表结构问题。若 DUAL 也失败,应优先检查:
SID_NAME、tnsnames 中的 SID 与 init<SID>.ora 文件名是否完全一致。
listener.ora 的 ORACLE_HOME 是否确实指向 Gateway Home。
PROGRAM 是否与安装组件一致:专用 SQL Server Gateway 使用 dg4msql。
HS_FDS_CONNECT_INFO 是否混用了逗号端口、端口与实例名。
是否在正确的 init 文件中设置 HS_FDS_TRACE_LEVEL=DEBUG。
9.2 ORA-28500 + Connection refused:网络端口层错误
ORA-28500: connection from ORACLE to a non-Oracle system returned this message: [Oracle][ODBC SQL Server Wire Protocol driver] Connection refused. Verify Host Name and Port Number. {08001} ORA-02063: preceding 2 lines from TIJIAN这个错误反而更接近成功:Gateway 已启动、连接串已被解析、驱动已经发起 TCP 连接。当前无需重建 DB Link,应直接检查 SQL Server 监听端口。
在 Gateway Windows 主机执行
Test-NetConnection192.0.2.20-Port 1443Test-NetConnection192.0.2.20-Port 1433| 测试结果 | 判断 | 处理 |
|---|---|---|
| 1443=False,1433=True | 实际监听默认端口 1433 | 将连接串改为 host:1433//database。 |
| 1443=False,1433=False | 端口未监听或被网络阻断 | 检查 SQL Server 服务、TCP/IP、绑定地址和防火墙。 |
| 1443=True | TCP 可达 | 继续检查登录、加密策略、数据库名和账号权限。 |
10. SQL Server 侧检查清单
在 SQL Server Configuration Manager 中启用 MSSQLSERVER 的 TCP/IP。
在 TCP/IP 属性的 IPAll 中确认 TCP Dynamic Ports 与 TCP Port;使用静态端口时清空动态端口。
修改网络协议或端口后重启 SQL Server 服务。
在 Windows 防火墙和中间网络设备上放通实际业务端口。
从 Gateway 主机使用 Test-NetConnection 或 sqlcmd 测试,不要只在 SQL Server 本机测试。
sqlcmd-S tcp:192.0.2.20,1443-U netstar-d HISDB--不带-P,让工具交互式提示密码,避免密码进入命令历史。11. 当 DUAL 成功、业务视图仍失败
只有在 DUAL@dblink 成功之后,才进入对象层排障。对于 SQL Server 视图,先在 SQL Server 查询输出字段类型,再逐列测试。
SELECTORDINAL_POSITION,COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALEFROMINFORMATION_SCHEMA.COLUMNSWHERETABLE_NAME='V_REGLISREQUEST'ORDERBYORDINAL_POSITION;11g Gateway 环境应重点关注以下类型:
datetime2、datetimeoffset、time、date
uniqueidentifier、xml
nvarchar(max)、varchar(max)、varbinary(max)
image、text、ntext
常用处理方式是在 SQL Server 创建面向 Oracle 的兼容视图,显式 CAST 为较传统的数据类型,并避免 SELECT *:
CREATEVIEWdbo.V_REGLISREQUEST_ORACLEASSELECTCAST(request_guidASvarchar(36))ASrequest_guid,CAST(created_atASdatetime)AScreated_at,CAST(xml_payloadASvarchar(4000))ASxml_payload,request_statusFROMdbo.V_REGLISREQUEST;12. 常见现象速查
| 现象/错误 | 最可能层级 | 优先动作 |
|---|---|---|
| ORA-02011 duplicate database link name | DB Link 元数据 | 查询 ALL_DB_LINKS,确认是否已有 PUBLIC 链接。 |
| ORA-28513 | Gateway Agent | 测试 DUAL、核对命名闭环、开启 DEBUG trace。 |
| ORA-28500 + Connection refused | TCP/SQL Server | 检查目标 IP、端口、SQL Server TCP/IP 与防火墙。 |
| ORA-02063 | 错误上下文 | 它只说明前面的错误来自哪个 DB Link,根因看上一条错误。 |
| status UNKNOWN | 静态 Listener 注册 | 通常正常;关注是否有 handler 以及 Agent 能否启动。 |
| DUAL 成功,业务视图失败 | 对象/数据类型 | schema 限定、逐列测试、创建兼容视图。 |
13. 上线前最终检查
Gateway 安装包为 5of7,安装组件为 Oracle Database Gateway for Microsoft SQL Server。
init<SID>.ora、listener SID_NAME、tnsnames SID 三处一致。
listener 的 ORACLE_HOME 指向 Gateway Home,PROGRAM=dg4msql。
TNS 描述符包含 (HS=OK)。
明确区分 Gateway Listener 端口与 SQL Server 业务端口。
Gateway 主机到 SQL Server 端口的 Test-NetConnection 成功。
DUAL@dblink 成功后再验证实体表和业务视图。
PUBLIC DB Link 使用最小权限账号,文档中无真实密码。
排障完成后将 HS_FDS_TRACE_LEVEL 恢复为 OFF,并妥善保留关键 trace。
已核对目标 Windows/SQL Server 版本的认证与补丁要求。
最终经验|好的排障不是一次猜中,而是让每一步都产生可区分的结果。本次从 ORA-28513 推进到 ORA-28500,正是因为先用 DUAL 隔离业务对象,再用一致的 SID 命名和规范连接串修复代理层,最后把问题准确落在 SQL Server 的 1443 端口。
14. 参考资料
Oracle Database Gateway 11g Release 2 文档库
Oracle Database Gateway for Microsoft Windows 安装与配置指南
Oracle Database Gateway for SQL Server 11g 用户指南
ORA-28513 官方错误说明
Oracle Software Delivery Cloud
说明:本文示例使用文档保留地址 192.0.2.0/24 和占位密码,实际部署请替换为本地环境参数。原文安装截图作为历史界面示意保留。