大家好,这里是公众号 DBA学习之路,分享一些学习数据库路上的知识和经验。

@TOC

前言

今天业务抛了个问题过来:Oracle 能不能直接查 TiDB?

第一反应是“这俩不是一套体系”,但转念一想,TiDB 在协议层面兼容 MySQL,而 Oracle 早就可以通过 透明网关 + ODBC + DBLink 访问 MySQL,那 TiDB 理论上也走得通。

实际动手验证了一下,结论很明确:确实可以。不需要做数据同步,不用引入中间服务,也不必改应用代码,只要在 Oracle 里建一个 DBLink,就能直接查询 TiDB 表。

本文记录的就是这次完整的落地过程。

环境信息

环境本身并不复杂,两端都是 CentOS 7.9,数据库版本也都算主流:

角色 系统 数据库类型 数据库版本
源端 Centos7.9 Oracle 19c
目标端 Centos7.9 TiDB v7.5.0

Oracle 端配置

透明网关检查

Oracle 19c 其实已经把 ODBC 透明网关准备好了,不需要再额外装什么组件。先简单确认一下:

1
2
3
4
5
6
7
[oracle@orcl:/home/oracle]$ cd $ORACLE_HOME/hs
[oracle@orcl:/u01/app/oracle/product/19.3.0/db/hs]$ dg4odbc

Oracle Corporation --- 2026-01-20 16:11:29.887228000

Heterogeneous Agent Release 19.0.0.0.0 - Production Built with
Oracle Database Gateway for ODBC

看到 Oracle Database Gateway for ODBC,说明没有问题。

安装 unixODBC

透明网关本身在 Oracle 里,但真正和外部数据库打交道,还是要靠系统层面的 ODBC。

CentOS 7 上直接用本地 YUM 源安装即可:

1
[root@orcl:/root]# yum install -y unixODBC*

装完之后,确认一下环境是否正常:

1
2
3
4
5
6
[root@orcl:/root]# odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini

这一步很关键,如果 ODBC 本身不干净,后面 Oracle 报错会非常“玄学”。

安装 MySQL ODBC 驱动

TiDB 在客户端看来就是 MySQL,这里直接使用 MySQL Connector/ODBC。

驱动从官方归档页下载即可:https://downloads.mysql.com/archives/c-odbc/

安装过程很简单:

1
[root@orcl:/root]# rpm -ivh mysql-connector-odbc-8.0.27-1.el7.x86_64.rpm

配置 ODBC 数据源

这里我直接在 /etc/odbc.ini 里定义 DSN,简单直观:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@orcl:/root]# cat> /etc/odbc.ini <<'EOF'
[ODBC Data Sources]
myodbc8w = MyODBC 8.0 UNICODE Driver DSN
myodbc8a = MyODBC 8.0 ANSI Driver DSN

[myodbc8w]
Description = Connector/ODBC 8.0 UNICODE Driver DSN
Driver = /usr/lib64/libmyodbc8w.so
SERVER = 192.168.31.222
USER = root
PASSWORD = testtest
PORT = 4000
DATABASE = cid_dsds_wex
OPTION = 0
TRACE = OFF
EOF

DSN 名称 myodbc8w,后面会反复用到,一定要前后一致。

验证 ODBC 连通性

在引入 Oracle 之前,先用 isql 把 ODBC 本身测通。

1
2
3
4
5
6
7
8
9
10
[oracle@orcl:/home/oracle]$ isql myodbc8w -v
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> show tables;

能正常 Connected!,说明 Linux → TiDB 这段链路已经没有问题,后续的问题只会发生在 Oracle 透明网关层。

配置 Oracle TNS

接下来开始配置 Oracle。

先在 tnsnames.ora 里定义一个服务名,注意这里的 HOST 是 Oracle 自己的 IP,不是 TiDB 的:

1
2
3
4
5
6
7
8
9
10
11
12
[oracle@orcl:/home/oracle]$ cat >> $ORACLE_HOME/network/admin/tnsnames.ora <<'EOF'
myodbc8w =
(DESCRIPTION=
(ADDRESS=
(PROTOCOL=TCP) (HOST= 192.168.31.221) (PORT=1521)
)
(CONNECT_DATA=
(SID=myodbc8w)
)
(HS=OK)
)
EOF

配置透明网关参数

透明网关的核心配置文件在,文件名必须是 init<SID>.ora,这里 SID 就是 myodbc8w

1
2
3
4
5
6
7
8
[oracle@orcl:/home/oracle]$ cat> $ORACLE_HOME/hs/admin/initmyodbc8w.ora <<'EOF'
HS_FDS_CONNECT_INFO=myodbc8w
HS_FDS_SHAREABLE_NAME=/usr/lib64/libodbc.so
HS_FDS_SUPPORT_STATISTICS=FALSE
HS_LANGUAGE = AMERICAN_AMERICA.AL32UTF8
HS_NLS_NCHAR = UCS2
HS_FDS_TRACE_LEVEL = debug
EOF

如果后续有字符集、SQL 转换相关问题,这个文件通常是第一排查点。

配置监听

透明网关是通过监听拉起的,需要在 listener.ora 中显式注册一个 SID:

1
2
3
4
5
6
7
8
9
10
11
[oracle@orcl:/home/oracle]$ cat>> $ORACLE_HOME/network/admin/listener.ora <<'EOF'
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(SID_NAME=myodbc8w)
(ORACLE_HOME=/u01/app/oracle/product/19.3.0/db)
(PROGRAM=dg4odbc)
(ENVS=LD_LIBRARY_PATH=/usr/lib64)
)
)
EOF

修改完成后,重载监听:

1
[oracle@orcl:/home/oracle]$ lsnrctl reload

验证 TNS 连通性

检查 TNS:

1
[oracle@orcl:/home/oracle]$ tnsping myodbc8w

只要不报错,说明监听侧已经能正确拉起 dg4odbc

创建 DBLink:

1
2
3
4
SYS@orcl SQL> create public database link testtidb
connect to "root"
identified by "testtest"
using 'myodbc8w';

查询验证

测试查询:

1
2
3
4
5
SYS@orcl SQL> select count(*) from test@testtidb ;

COUNT(*)
----------
44527956

结果正常返回,说明链路已经完全打通。

总结

从 Oracle 到 TiDB,看起来是两套体系,其实中间那条桥一直都在。ODBC + 透明网关 + DBLink,这套“老技术”,在今天依然非常稳。

只要分清楚每一层的职责,先通 ODBC,再通 Oracle,整个过程反而比想象中要顺得多。