odbc_fdw 使用手册
1 概述
odbc_fdw 用于让 UDB 通过 ODBC 访问外部数据源,并把外部表映射为 UDB 内可查询的外部表。
本文示例:以 “UDB 作为外部数据源” 举例(UDB ODBC Driver + 远端 UDB)。
1.1 适用范围与选型建议
当目标数据源已有成熟专用 FDW(例如 MySQL/Oracle 等),优先评估与使用专用 FDW(例如 mysql_fdw/oracle_fdw),ODBC 方案通常用于兼容性接入。
ODBC 方案对不同数据源的兼容程度,取决于对应数据源的 ODBC Driver 能力与行为;配置项与可用特性可能存在差异。
1.2 概念与术语
unixODBC(Driver Manager,驱动管理器):负责读取
odbcinst.ini/odbc.ini,加载 ODBC Driver,并转发 ODBC 调用。ODBC Driver(目标数据源的 ODBC 驱动):不同数据源的驱动不同;在 Linux 上通常表现为驱动库文件(
.so)及其依赖库。驱动库文件(
.so):ODBC Driver 在 Linux 下的落地形态之一,路径通常填写在odbcinst.ini的Driver64中。驱动注册文件
odbcinst.ini:把“驱动名”映射到驱动库文件路径(.so)。DSN(Data Source Name,数据源名):
odbc.ini的节名(例如[REMOTE_UNVDB]);UDB 侧CREATE SERVER ... OPTIONS (dsn 'REMOTE_UNVDB')通过 DSN 引用它。DSN 配置文件
odbc.ini:定义数据源名(DSN)及连接参数;UDB 侧CREATE SERVER ... OPTIONS (dsn '...')通过 DSN 引用它。
1.3 工作链路
SQL 查询
→ UDB 服务进程
→ odbc_fdw
→ unixODBC(Driver Manager,驱动管理器)
→ ODBC Driver(目标数据源的 ODBC 驱动)
→ 远端数据源
2 路径替换说明
文中 <安装包目录>、<数据目录> 均为占位符,读者需替换为自己实际路径。
常见示例(仅示意):
安装包目录:例如
/home/unvdb/work/UDB-TX-26-ALL数据目录:例如
/home/unvdb/work/unvdb-data
3 配置编写:准备驱动、odbcinst.ini、odbc.ini
3.1 准备 ODBC Driver(按目标数据源选择)
odbc_fdw 通过 ODBC 访问外部数据源时,必须先准备“目标数据源对应的 ODBC Driver”(驱动库 .so 及其依赖库)。
常见数据源的驱动获取方式不同:
UDB:驱动由交付物提供(见下文 3.1.1)
其他数据源:应获取对应厂商/发行版提供的 ODBC Driver,并按其文档完成安装与注册
3.1.1 示例:使用交付物自带的 UDB ODBC Driver(zip 交付,需解压)
交付物中 UDB ODBC Driver 通常位于:
<安装包目录>/Interface/ODBC/
常见驱动包文件名(以实际交付物为准):
unvdb_odbc_centos_amd64.zipunvdb_odbc_centos_aarch64.zip
一般 x86_64 机器使用 amd64,aarch64 机器使用 aarch64。
解压建议:把驱动与其依赖库解压到 <安装包目录>/lib/,便于与交付包其它库一起由 LD_LIBRARY_PATH 管理。
在继续之前,建议确认 <安装包目录>/lib/ 中已包含 unixODBC 运行库(以实际交付为准):
libodbc.so.2libodbcinst.so.2
unzip <安装包目录>/Interface/ODBC/unvdb_odbc_centos_amd64.zip -d <安装包目录>/lib/
解压后通常可见(以实际包内为准):
驱动:
unvdbodbcw.so、unvdbodbca.so依赖:
libpq.so.5、libssl.so.10、libcrypto.so.10
下文统一用 <ODBC驱动目录> 指代驱动所在目录,默认即 <安装包目录>/lib/。
常见提示与处理建议(zip 解压场景):
解压过程中可能遇到类似提示:目标目录已存在同名文件(例如
libpq.so.5已存在且为软链接),unzip会询问是否覆盖。处理原则:不要盲目覆盖。优先选择不覆盖(输入
n),先完成部署并验证可用性;如后续确需替换,再在明确版本与依赖关系后进行调整。
3.1.2 示例:其他数据源的 ODBC Driver 获取方式(非 UDB)
不同数据源的 ODBC Driver 获取方式不同,常见两类如下:
方式 A:通过系统包管理器安装(示例,仅示意,包名以发行版仓库为准)
sudo yum install -y mysql-connector-odbc
说明:
系统安装后驱动库通常位于系统目录(例如
/usr/lib64/)仍需在
odbcinst.ini注册驱动条目,并在odbc.ini配置 DSN
以 MySQL 为例,安装后常见驱动库文件为:
Unicode:
/usr/lib64/libmyodbc9w.soANSI:
/usr/lib64/libmyodbc9a.so
查看安装到哪些文件(推荐):
rpm -ql mysql-connector-odbc | egrep 'libmyodbc|README|odbc' | sort
方式 B:手工获取驱动并放置到固定目录(示例)
将驱动库文件(
.so)复制到<安装包目录>/lib/(或系统标准库目录)若放在
<安装包目录>/lib/,通常可复用既有LD_LIBRARY_PATH配置
3.2 编写 odbcinst.ini(注册驱动)
在 <数据目录>/odbc/odbcinst.ini 增加(按实际路径替换):
[UNVDB]
Description = ODBC Driver for UDB
Driver64 = <ODBC驱动目录>/unvdbodbcw.so
FileUsage = 1
说明:
[UNVDB]是驱动名;DSN 里通过Driver = UNVDB引用,必须一致默认推荐使用
unvdbodbcw.so(Unicode/Wide);除非明确需要兼容旧调用链,否则不建议选unvdbodbca.so不建议通过“随意建立软链接”伪装缺失库;应补齐匹配版本的库文件,或统一选择“交付包自带”或“系统安装”的一套库
3.3 编写 odbc.ini(配置 DSN)
在 <数据目录>/odbc/odbc.ini 增加(按实际参数替换):
[REMOTE_UNVDB]
Driver = UNVDB
Description = Remote UDB via ODBC
Database = unvdb
Servername = 127.0.0.1
Port = 5678
UserName = unvdb
重要说明:
上述 DSN 字段为 “UDB ODBC Driver” 的示例。不同 ODBC Driver 支持的 DSN 参数名可能不同,应以对应驱动文档/示例为准。
常见误配置(供排障参考):某些数据源(例如 MySQL)的 ODBC Driver 同时支持
Socket(本机 Unix Socket)与Server/Port(TCP),两者属于不同连接方式,不应同时配置,应二选一。
安全建议:
不建议在
odbc.ini明文写Password口令优先在 UDB 内通过 USER MAPPING 配置(见第 5 章“数据库操作”)
4 暴露配置:env.sh(UDB 与 ud_sql 启动前都要 source)
关键点:odbc_fdw 由 UDB 服务进程执行外部访问,因此 ODBCSYSINI/ODBCINI/LD_LIBRARY_PATH 必须在启动服务进程之前就生效;仅在 ud_sql 前设置通常不足以让已启动的服务进程生效。
推荐把环境变量写进 <数据目录>/env.sh,并在启动服务进程与运行 ud_sql 前都 source 一次。
说明:
如果你把目标数据源的 ODBC Driver(以及依赖库)放在
<安装包目录>/lib/,且现场env.sh原本就已把<安装包目录>/lib/加入LD_LIBRARY_PATH,通常不需要为了 odbc_fdw 额外改动LD_LIBRARY_PATH。ODBCSYSINI/ODBCINI用于让 unixODBC 找到odbcinst.ini/odbc.ini,通常是启用 odbc_fdw 后新增需要设置的环境变量。
示例(读者替换为自己的实际路径):
export LD_LIBRARY_PATH=<安装包目录>/lib:${LD_LIBRARY_PATH:-}
export ODBCSYSINI=<数据目录>/odbc
export ODBCINI=<数据目录>/odbc/odbc.ini
使用方式:
source <数据目录>/env.sh
说明:
若你修改了 env.sh 或 DSN 配置,需重启 UDB 服务进程使其生效
5 数据库操作(示例:连接外部 UDB)
本章示例目标:在本地 UDB 中创建外部表,查询到外部 UDB 中的表数据。
前置:
已按第 3~4 章完成 ODBC Driver 准备/安装、
odbcinst.ini、odbc.ini、env.sh启动 UDB 服务进程前、以及运行
ud_sql前都执行:source <数据目录>/env.sh
在 ud_sql 中执行(按实际 DSN/账号/表名替换):
CREATE EXTENSION IF NOT EXISTS odbc_fdw;
DROP SERVER IF EXISTS odbc_svr CASCADE;
CREATE SERVER odbc_svr FOREIGN DATA WRAPPER odbc_fdw OPTIONS (dsn 'REMOTE_UNVDB');
CREATE USER MAPPING FOR CURRENT_USER SERVER odbc_svr
OPTIONS (odbc_UID 'unvdb', odbc_PWD '******');
DROP FOREIGN TABLE IF EXISTS ft_test_demo;
CREATE FOREIGN TABLE ft_test_demo (
id int,
username text
) SERVER odbc_svr OPTIONS (schema 'public', table 'test_demo');
SELECT * FROM ft_test_demo ORDER BY id;
说明:
CREATE SERVER ... OPTIONS (dsn '...')的dsn固定引用odbc.ini的 DSN 名;同一个odbc_fdw也可通过不同 DSN 连接不同数据源。CREATE USER MAPPING ... OPTIONS (odbc_UID '...', odbc_PWD '...')属于连接属性;不同数据源账号口令、认证方式以对应 ODBC Driver 支持为准。CREATE FOREIGN TABLE ... OPTIONS (...)中的选项含义与“目标数据源”相关:对 UDB(本示例):常用
schema+table对 MySQL:通常只写
table;目标库名建议写在 DSN(odbc.ini的Database = ...)中
MySQL 示例(仅示意,参数按实际替换):
DROP SERVER IF EXISTS mysql_svr CASCADE;
CREATE SERVER mysql_svr FOREIGN DATA WRAPPER odbc_fdw OPTIONS (dsn 'MYSQL_DSN');
CREATE USER MAPPING FOR CURRENT_USER SERVER mysql_svr OPTIONS (odbc_UID 'demo_user', odbc_PWD '******');
DROP FOREIGN TABLE IF EXISTS ft_mysql;
CREATE FOREIGN TABLE ft_mysql (
id int,
name text
) SERVER mysql_svr OPTIONS (table 't1');
限制说明:
当前版本
odbc_fdw外部表为只读,不支持INSERT/UPDATE/DELETE。对外部表执行写入会报错,例如:ERROR: cannot insert into foreign table ...
6 常见错误排查:Connecting to driver 与证据采集
6.1 推荐排障顺序
1)确认 <数据目录>/env.sh 已包含 ODBCSYSINI/ODBCINI,且在启动服务进程前已 source 并重启服务进程
2)确认 ODBC Driver 已就绪(例如驱动库文件 .so 位于 <安装包目录>/lib/ 或系统目录),且 odbcinst.ini 的 Driver64 指向实际 .so
3)采集 UDB 日志(见 6.2)
4)开启 unixODBC trace(见 6.3)并复现报错
6.2 采集 UDB 日志(在 ud_sql 内执行)
定位日志位置:
SHOW logging_collector;
SHOW log_directory;
SHOW log_filename;
如需快速确认日志相关配置:
SELECT name, setting, unit
FROM pg_settings
WHERE name LIKE 'log\_%' ESCAPE '\'
OR name = 'logging_collector'
ORDER BY name;
6.3 启用 unixODBC trace(定位 Driver Manager/驱动侧错误)
在 <数据目录>/odbc/odbc.ini 的对应 DSN 节增加(示例):
[REMOTE_UNVDB]
Trace = Yes
TraceFile = <数据目录>/odbc/trace/unixodbc.trace
注意:
需要保证
TraceFile目录存在且 UDB 服务用户有写权限trace 文件可能增长很快,排障后应关闭
6.4 常见原因速查
Driver64路径错误:odbcinst.ini指向的.so不存在或权限不可读依赖库缺失:
unvdbodbcw.so依赖的libpq/libssl/libcrypto不在动态库搜索路径服务进程未读到 ini:UDB 服务进程环境里缺
ODBCSYSINI/ODBCINI(仅ud_sql设置无效)DSN/驱动名不一致:
odbc.ini的Driver = ...与odbcinst.ini的段名不一致多套库混用:系统与交付包同名库被混合加载导致异常
7 安全建议
生产环境使用最小权限账号访问远端
避免在
odbc.ini明文写口令;口令优先放到 USER MAPPING限制
odbc.ini/odbcinst.ini文件权限,确保仅 UDB 服务用户可读