☰
Ubuntu 22.04 安装 ODBC 18:注册驱动与 DSN 配置完全指南
2026/10/11 20:49:35 网站建设 项目流程

Ubuntu 22.04上安装ODBC 18,我前前后后试过三种方式,最后稳定下来的还是官方软件源配合unixODBC的做法。这篇记录不是把Apt命令念一遍,而是把整个思路拆开,重点说安装之后的驱动注册、DSN写法以及各种报错的定位方法,希望你照着走一遍能一次过。

先交代一下背景。ODBC 18本质上是你和数据库之间的一层翻译官,它在应用代码和数据库原生协议之间做了统一转换。不同的数据库厂商会提供不同版本的ODBC驱动,我这里讲的这套安装流程,在所有基于deb的Ubuntu/Debian系统上基本通用。如果你是刚上手的开发者,准备在Linux服务器上让应用连数据库,这一篇可以直接抄作业。

1. 安装前先把思路理清楚

1.1 ODBC 18到底解决了什么问题

很多同学一听到ODBC就觉得是旧时代的东西,实际上它在现代开发里依然很常见,尤其是企业应用中需要跨语言调用数据库时。ODBC 18这个版本和老的2.x驱动相比,最主要的变化在两点:一是默认开启加密连接,对SSL/TLS的要求更高;二是增强了服务端证书校验和协议版本兼容性,算是顺应了现在数据库安全基线普遍提高的现状。

在Ubuntu 22.04里,系统仓库自带的unixODBC版本已经比较新,这反而是好事,因为新版unixODBC对ODBC 18的驱动注册、配置读取都更友好。真正的问题是ODBC 18的驱动主程序不在系统默认软件源里,需要你自己加源。知道这一点,后面碰到“找不到软件包”这类报错时,就不会一头雾水了。

1.2 为什么我不建议直接下载deb包

我最早干过一件偷懒的事:去ODBC 18发布方的官网直接下载deb安装包,扔到服务器上dpkg -i强装。结果装完发现它依赖一个更高版本的libcrypto,系统里也有,但路径对不上,跑起来直接段错误。后来换成官方源安装,apt自动解决依赖,安装过程干净利落,前后不到三分钟。

还有一个更现实的问题:后续安全补丁。数据库驱动这种底层组件,一旦有安全更新,你总不能每天上网站手动看版本号。走软件源之后,apt upgrade就能跟着系统一起升级,运维成本低很多。所以我的建议很明确:正式环境别搞手工拷贝,老老实实走源。

1.3 完整安装链路是这样的

在你动手之前,先在脑子里建立一张路线图,后面操作就不会慌:

  1. 检查系统版本和CPU架构
  2. 安装curl、gnupg、unixODBC等基础组件
  3. 导入ODBC 18官方GPG签名公钥
  4. 写入APT软件源并更新索引
  5. 安装ODBC 18驱动主包
  6. 确认驱动已被unixODBC识别
  7. 配置DSN并做连通性测试

这篇文章会覆盖这七步。下面每一步我都会说明命令背后的原因,避免你只复制不思考。

2. 开始安装:从基础工具到驱动主包

2.1 先确认你的系统环境

很多人装失败,不是因为命令错了,而是系统版本不是22.04,或者装的是32位系统。ODBC 18对平台有明确要求,不满足硬上大概率会出现库文件加载失败。

打开终端执行:

cat /etc/os-release uname -m

os-release里能看到VERSION_ID="22.04",说明系统版本没问题。uname -m输出x86_64,说明是64位系统。如果你的机器是ARM架构,比如树莓派或某些云服务器,后面源地址里的arch=amd64要改成arm64,驱动包名可能也不一样,这一点要格外注意。

在执行后续安装之前,顺手把系统软件源更新一下,避免因为本地索引太旧导致一些包找不到:

sudo apt update

2.2 安装基础工具和unixODBC

接下来安装这次会用到的工具包。unixODBC是Linux下的ODBC驱动管理器,没有它,ODBC 18装好了也不会被应用调用,所以这一步不能跳。

sudo apt install -y curl apt-transport-https gnupg unixodbc unixodbc-dev

这些包各自的作用:

  • curl:从网上拉取GPG公钥和源信息。
  • apt-transport-https:让apt支持通过HTTPS访问软件源。
  • gnupg:用于导入和转换签名公钥。
  • unixodbc:ODBC驱动管理器本体,负责加载驱动、解析DSN。
  • unixodbc-dev:开发头文件,等会儿你编译连接代码或装某些语言扩展时会用到。

有些人会问,我只跑应用,不开发,为什么还要装unixodbc-dev?答案是很多语言的ODBC库在安装阶段会自动检测这个头文件,缺了它,后续你写Python或Node.js代码时会明明驱动装了却连不上,问题特别难排查。所以我一般建议顺手装上,体积不大,换来的是少踩一个坑。

2.3 导入官方GPG公钥

APT源如果不用数字签名验证,就相当于你下载的软件包可能被中间人篡改。这不是危言耸听,尤其在内网环境或者用了不靠谱的镜像的时候。所以第二步是把ODBC 18发布方用于签名软件包的公钥导入到系统中。

早期教程喜欢用apt-key add,但这个命令在新版Ubuntu里已经标记为废弃,正确的做法是把公钥转换成二进制格式,放到/usr/share/keyrings/目录,然后通过源配置文件里的signed-by参数指定它。

具体命令如下,其中带尖括号的地址需要替换成ODBC 18发布方文档里公布的真实地址:

curl -fsSL <公钥下载地址> | sudo gpg --dearmor -o /usr/share/keyrings/odbc18-archive-keyring.gpg

这里--dearmor的作用是把从网络上下载的文本格式公钥转换成二进制格式,gpg和apt都能直接识别。转换完可以通过下面的命令确认公钥已经写进去:

ls -l /usr/share/keyrings/odbc18-archive-keyring.gpg

如果文件存在且大小为几百字节,说明导入成功。这里有个小细节:不要在公钥地址里加sudo,你只需要把下载结果重定向给gpg即可,权限只在写输出文件那一刻需要。

2.4 写入APT源文件

导入公钥之后,需要告诉apt从哪个仓库拉取ODBC 18的安装包。这一步最常见的错误是把源地址写死成某个旧版本,结果更新之后找不到包。

推荐的做法是让系统自己生成版本代号:

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/odbc18-archive-keyring.gpg] <软件源地址> $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/odbc18.list

这里$(lsb_release -cs)会输出jammy,也就是Ubuntu 22.04的代号,这样即使以后系统升级到其他版本,重新执行一次也能生成对应的源,不用手改。arch=amd64是硬性指定架构,防止在配置了多架构的系统上误装i386版本依赖。

写完源之后,查看一下文件内容确保格式正确:

cat /etc/apt/sources.list.d/odbc18.list

然后更新软件源索引。这一步如果报“The repository does not have a Release file”或者“404 Not Found”,多半是源地址写错了,或者该发布方还不支持当前系统代号,需要去官方文档找历史源地址,而不是在论坛上随便抄一条。

sudo apt update

更新过程中留意有没有关于这个源的警告,正常情况下应该是干净的输出。如果看到类似“No priority”的提示,可以暂时忽略,不影响安装。

2.5 安装ODBC 18驱动主包

源配置正常之后,先搜一下仓库里的包名,避免记错:

apt-cache search odbc18

不同发行方给的包名不一样,有的叫odbc18,有的叫msodbcsql18这种风格,还有的会把驱动拆成运行时包和开发包。确认包名后,下一步就是安装了。

ODBC 18这类驱动一般带有最终用户许可协议,安装时如果不接受会被中断。用下面这种方式安装,相当于提前把许可证标记为接受:

sudo ACCEPT_EULA=Y apt install -y <ODBC18包名>

ACCEPT_EULA=Y这个环境变量很关键,我第一次装的时候没加,结果在Tty模式下卡在交互确认界面。如果你在无人值守的脚本里忘了这个变量,安装脚本会一直挂起,最后超时失败。加了它,整个安装过程会静默完成,输出里会看到驱动库文件被放到了/usr/lib/x86_64-linux-gnu/下,并且自动往/etc/odbcinst.ini里注册了一条驱动信息。

到这里,ODBC 18就算装上系统了。别急着写代码,先验证驱动注册是否成功。

3. 驱动注册检查与连接配置

3.1 先确认驱动被系统认出来了

ODBC 18安装完成后,所有集成能不能生效,全看ODBC驱动管理器认不认这个驱动。安装包通常会自动往配置里写一条,但我遇到过某些从二进制包拷贝出来的环境,驱动没有注册,应用怎么都找不到它。

跑下面这条命令:

odbcinst -q -d

如果输出里有类似ODBC Driver 18这样的名字,说明驱动注册成功。如果列表为空,就得手动检查配置文件。

先用下面命令查看ODBC管理器实际读取的配置文件路径:

odbcinst -j

这条命令特别实用,它会显示三样东西:odbcinst.ini路径、odbc.ini路径以及数据源文件路径。如果你系统里装过多个unixODBC,很可能会看到路径指向某个自定义位置,这时候不要慌,只要记住应用运行时用的是哪个ODBC管理器,配置保持一致即可。

3.2 手动驱动注册姿势

如果驱动没有自动注册,或者你想要换一个驱动库路径,就自己编辑odbcinst.ini。文件位置用上一步odbcinst -j查到的,常见的是/etc/odbcinst.ini。在文件末尾新增一节:

[ODBC Driver 18] Description=ODBC Driver 18 for the target database Driver=/usr/lib/x86_64-linux-gnu/libodbc18.so

方括号里的名字就是驱动逻辑名,后面DSN配置里Driver=字段引用的就是这个名字。如果你不确定库文件具体路径,用find /usr/lib -name '*odbc*18*'查一下,记录下来后再改配置,不要靠猜。

修改完配置,再执行一次:

odbcinst -q -d

确认输出里出现刚才写的驱动名,驱动注册环节就结束了。

3.3 配置DSN数据源

DSN相当于给数据库连接信息起了一个别名,之后应用里不用写一长串连接参数,直接引用别名就行。系统级和用户级的DSN分别放在/etc/odbc.ini和~/.odbc.ini,系统级需要sudo权限才能写。

下面是一个常见的DSN配置块,我会逐行解释参数:

[demodb] Driver=ODBC Driver 18 Server=192.168.1.20 Port=1433 Database=testdb Encrypt=yes TrustServerCertificate=no
  • Driver=的值必须对应odbcinst.ini里的驱动逻辑名,大小写和空格都不能错。
  • Server=是数据库服务端IP或主机名。
  • Port=是端口,按默认的数据库端口来填。
  • Database=是默认访问的库名。
  • Encrypt=yes表示启用TLS加密传输,ODBC 18默认就是加密,建议显式写出来。
  • TrustServerCertificate=no表示不自动信任服务器证书,避免中间人攻击。如果你自己签发的证书都配好了,保持no;如果只是本地测试,可以临时改成yes,但千万别带到生产环境。

配置写完后,可以用odbc::isql的打印命令快速验证DSN是否能被解析到:

odbcinst -q -s

如果列表里出现了demodb,说明DSN配置已经被管理器读取到了。

3.4 用命令行真正连一次

DSN配置好,不要直奔代码,先用ODBC自带的命令行工具isql做一次连通性测试。这样能把“配置问题”和“代码问题”隔离开。

isql -v demodb your_user your_password

如果配置没问题,你会看到类似Connected!的提示,然后进入SQL交互界面。你可以先执行一句:

SELECT 1;

能返回1就说明从驱动到数据库服务端的完整链路已经通了。如果报错,先别急着搜代码问题,因为命令行工具都连不上,应用层肯定也连不上。此时问题大概率出在三处:DSN配置、网络连通性、驱动库文件路径。

退出isql直接输入quit回车即可。

3.5 常见语言里的调用方式

命令行测通之后,再进开发环节就清晰很多。这里举三种最常用的调用方式,基本覆盖大部分场景。

Python使用pyodbc包,连接串可以直接引用DSN:

import pyodbc conn_str = "DSN=demodb;UID=your_user;PWD=your_password" with pyodbc.connect(conn_str) as conn: cursor = conn.cursor() cursor.execute("SELECT 1") print(cursor.fetchall())

Node.js可以使用odbc这个原生模块,初始化方式类似:

const odbc = require("odbc"); async function main() { const conn = await odbc.connect("DSN=demodb;UID=your_user;PWD=your_password"); const result = await conn.query("SELECT 1"); console.log(result); await conn.close(); }

Go语言一般用database/sql配合go-odbc驱动,连接串同样可以是DSN形式:

package main import ( "database/sql" "fmt" _ "github.com/某go-odbc驱动" ) func main() { db, err := sql.Open("odbc", "DSN=demodb;UID=your_user;PWD=your_password") if err != nil { panic(err) } conn, err := db.Conn() if err == nil { fmt.Println("connected") } conn.Close() }

这些代码本身不复杂,复杂的是背后的库依赖。你只要记住一个原则:命令行能连、代码连不上,优先查语言模块的编译链路,看它有没有链接到unixodbc的库文件,而不是怀疑ODBC 18本身有问题。

4. 常见问题与排查实录

4.1 安装时报“Unable to locate package”

这是新手最容易遇到的问题。原因基本可以锁定在软件源没有被正确写入,或者源更新失败。

排查顺序:

  1. 执行cat /etc/apt/sources.list.d/odbc18.list,确认文件名和内容都在。
  2. 执行sudo apt update,看结尾有没有Failed to fetch或者404 Not Found。
  3. 如果有404,说明源地址不支持当前系统版本,去发布方文档找Ubuntu 22.04对应的源地址,不要把jammy改成focal硬凑。
  4. 如果是“Missing signed-by”之类的报错,说明apt找不到公钥文件,检查/usr/share/keyrings/下有没有对应的.gpg文件,文件权限是否644。

我遇到过最坑的情况是源地址里把main写成了main contrib导致索引出错,所以看到这种提示,优先检查自己的输入和官方文档有没有出入。

4.2 驱动列表里没有“ODBC Driver 18”

安装完成但odbcinst -q -d看不见驱动,这个问题最常见的原因就是安装包在安装时无法定位系统里的unixODBC配置文件。

先执行odbcinst -j,看看当前ODBC管理器找的是哪个配置路径。如果你的系统中存在多个版本的unixODBC,比如一个来自系统包,一个来自源码编译,安装驱动时它写入的是其中一份配置,而应用运行时用的是另一份,自然就找不到。

解决办法是统一ODBC管理器。简单粗暴的方式是卸载源码版,只保留系统包;或者把驱动注册信息手动写到odbcinst -j报告的那个配置里。还有一个小技巧,设置环境变量ODBCSYSINI指定配置目录,这样能临时让所有工具都读同一份配置:

export ODBCSYSINI=/etc

不过这种环境变量方案不能彻底解决多管理器冲突,长期来看还是要清掉多余版本。

4.3 连接时报SSL/TLS证书错误

ODBC 18因为默认强制加密,证书相关的报错比老驱动频繁得多。常见错误信息包含certificate verify failed或者SSL routines。

处理判断逻辑:

  • 如果服务端使用的是自签名证书,而你没有把该证书加到系统信任链,测试阶段可以在DSN里临时设置TrustServerCertificate=yes。这里再次强调,这只适合内网测试,生产环境千万不能这么干。
  • 如果服务端使用公网证书但证书链不完整,需要把中间证书安装到/usr/local/share/ca-certificates/,然后执行sudo update-ca-certificates。
  • 如果数据库服务端只支持TLS 1.0/1.1,ODBC 18大概率直接拒绝,因为这类新驱动要求TLS 1.2以上。这种情况只能升级数据库服务端的TLS协议,客户端这边没法妥协。

我之前遇到一次很有意思的问题:本地开发机器连接正常,测试服务器连接报证书错,排查半天发现是服务器时区不对,导致证书有效期校验失败。改完时区,问题立刻消失。这种坑如果你遇到,也不用太意外。

4.4 中文乱码和字符集问题

ODBC 18默认的字符集行为可能与老应用预期不一致,中文乱码问题通常出现在从旧版本迁移过来的系统上。

如果是Python应用,连接串里可以指定ClientCharset=UTF-8参数,或者在使用pyodbc时确保数据库表结构使用UTF-8排序规则。如果是C/C++程序,检查SQLSetConnectAttr里配置的编码属性,不要用系统的locale去想当然。

还有一个容易被忽略的地方:isql显示乱码并不代表驱动返回的数据真的乱,有时候只是终端显示编码不对。你可以把查询结果导出成文件,用十六进制工具看一下,确认服务端返回的字节到底是GBK还是UTF-8,再决定在应用层做转换。

4.5 权限问题导致连接失败或配置读取失败

DSN和驱动配置文件如果权限设置太严格,普通服务账号可能读不了,导致应用启动时报“Can't open lib”或者“DSN not found”。

排查权限问题,我用下面的命令快速定位:

namei -l /etc/odbc.ini /etc/odbcinst.ini

这个命令会列出路径上每一层目录的权限。注意不光文件本身,父目录如果缺少执行权限,文件照样读不到。一般建议配置文件权限使用644,目录权限至少755。如果应用运行在systemd服务里,还要检查服务的ProtectSystem、ReadOnlyPaths等沙箱参数,这些参数可能会让进程无法读取/etc下的配置。

另一个小坑是某些服务强制绑定环境变量,比如进程里设置了ODBCINI指向不存在的路径,导致应用永远读不到真正的DSN。可以在服务启动命令里用odbcinst -j输出的正确路径覆盖它,或者删掉无效的环境变量定义。

4.6 动态库加载失败

如果启动应用时提示找不到libodbc.so或者libodbc18.so,先用ldconfig确认系统缓存里有没有这个库:

ldconfig -p | grep odbc

如果没有输出,说明库文件的路径不在/etc/ld.so.conf.d/里,需要新建一个配置文件:

echo "/usr/lib/x86_64-linux-gnu" | sudo tee /etc/ld.so.conf.d/odbc.conf sudo ldconfig

执行完再跑一次ldconfig -p | grep odbc,确认能看见对应的库文件。这一步是很多从源码编译安装的人会踩的坑,官方deb包通常已经处理好了,但基本排查思路你得知道。

关于安装顺序和版本选择的一点体会

ODBC 18安装本身并不算复杂,真正耗时间的往往是环境里的历史遗留问题。我在实际部署中遇到过很多次“驱动装了,应用却用它不到”的情形,最后定位到都是系统里并存着两套ODBC管理器导致的。所以我的建议是:装驱动之前先检查unixODBC版本,用odbcinst -j确认配置文件路径,让整个系统保持单一份odbcinst.ini和odbc.ini。

另外,ODBC 18的新安全特性在旧运维惯性里容易被忽略。以前驱动默认不加密,很多连接串里根本没写过证书相关参数,升级到18之后突然Fail,这并不是驱动坏了,而是安全默认值变了。记住这一点,排查证书问题时思路会快很多。

这次用ODBC 18驱动验证的时候,我还发现一个实用的小技巧:连接出问题时,不要只在应用层打日志,可以临时打开ODBC管理器的事件日志。不同unixODBC版本的日志开关位置不太一样,但通常都会在配置里预留日志文件路径和日志级别字段。打开这个功能之后,你会看到驱动在哪个阶段失败,是解析参数失败还是网络握手失败,排障效率直接翻倍。定位完问题,再把日志关掉就行,避免生产环境持续写日志。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询