dg4odbc是监听器按需派生的外部程序,非常驻进程;关键在于监听器能否正确识别sid、加载init.ora参数、调用odbc驱动并完成连接协商,所有配置项(路径、命名、权限、大小写、hs=ok)必须严格一致。

DG4ODBC 服务本身不是“启动后就一直运行”的常驻进程,而是由 Oracle 监听器按需派生的外部程序。配置不等于安装完就能用,关键在于监听器能否正确识别 SID、加载参数、调用 ODBC 驱动并完成连接协商。
确认 DG4ODBC 可执行文件存在且权限正确
Oracle 透明网关(DG4ODBC)必须位于 $ORACLE_HOME/hs/bin/ 下,且对运行监听器的用户(通常是 oracle)可执行:
-
ls -l $ORACLE_HOME/hs/bin/dg4odbc—— 输出应含x权限,如-rwxr-xr-x - 若缺失,说明网关未安装或安装路径错误;
runInstaller必须勾选 “Database Gateway for ODBC” 选项 - 若权限不足,用
chmod +x $ORACLE_HOME/hs/bin/dg4odbc修复,不要用root运行它 - RAC 环境下注意:网关应装在 Grid 用户可访问的共享路径,但监听器由 Grid 启动,
ORACLE_HOME指向网关家目录而非数据库家目录
init<sid>.ora</sid> 文件必须放在正确路径且命名匹配
监听器通过 SID_NAME 查找对应初始化参数文件,文件名必须是 init<sid>.ora</sid>,且必须放在 $ORACLE_HOME/hs/admin/ 目录下(不是 network/admin):
- 例如
SID_NAME = mysqlgw→ 文件必须为$ORACLE_HOME/hs/admin/initmysqlgw.ora -
HS_FDS_CONNECT_INFO是唯一必填项,格式为DSN_NAME(即/etc/odbc.ini中定义的段名),不能写成 IP+端口 -
HS_FDS_TRACE_LEVEL = OFF生产环境必须关闭;调试时设为255,日志会生成在$ORACLE_HOME/hs/log/下,文件名含mysqlgw和时间戳 - 字符集建议显式指定:
HS_NLS_NCHAR = AL32UTF8,避免 MySQL 的utf8mb4与 Oracle 的AL32UTF8映射异常
listener.ora 中的 SID_DESC 必须严格匹配
监听器靠 SID_DESC 块识别何时该调用 dg4odbc,任何字段错位都会导致 ORA-28545:
-
SID_NAME必须和tnsnames.ora中的SID、init<sid>.ora</sid>文件名中的<sid></sid>完全一致(区分大小写) -
PROGRAM = dg4odbc—— 不能写成dg4odbc.sh或带路径,监听器会自动在$ORACLE_HOME/hs/bin/下查找 -
ORACLE_HOME必须指向网关安装路径,不是数据库的$ORACLE_HOME;若两者相同,仍需显式写出 - 监听端口(如
PORT = 1522)应避开数据库监听端口(1521),否则lsnrctl start会失败
tnsnames.ora 的 HS=OK 不是可选项
客户端通过 TNS 别名访问网关时,HS=OK 是强制标记,告诉 Oracle 客户端这是一个异构连接,需启用 Heterogeneous Services 协议:
- 示例片段:
MYSQLGW = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1522)) (CONNECT_DATA = (SID = mysqlgw)) (HS = OK) ) - 漏掉
(HS = OK)会导致ORA-02063(紧接着ORA-28545),因为 Oracle 尝试用原生 Oracle 协议连接,而dg4odbc不响应 - 该文件必须放在监听器所在用户的
TNS_ADMIN目录下(通常是$ORACLE_HOME/network/admin),不是数据库实例的tnsnames.ora -
tnsping MYSQLGW成功只代表网络通、监听收到请求;真正验证要跑sqlplus user@MYSQLGW并查表
initmysqlgw.ora 放错目录,或 SID_NAME 多个空格,tnsping 都能过,但 SELECT 一定报 ORA-28545 —— 因为监听器根本没把请求转给 dg4odbc。











