☰
PHP连接达梦数据库DM8实战:从Linux安装到ODBC配置避坑指南
2026/10/5 7:33:24 网站建设 项目流程

最近被一个 PHP 项目搞得有点头大:数据库不用 MySQL,也不用 Oracle,必须用达梦数据库。以前没在生产环境摸过 DM8,心里确实没底。从下载安装包开始,到 PHP 成功连上达梦数据库,整个过程走下来,半天左右就通了。这篇不是官方文档的复读,是我自己实际走过一遍的笔记,包含 Linux 上的安装命令、PHP 侧连接配置,以及几个让我浪费了不少时间的坑。适合两类人:一类是要在 Linux 上装达梦并手动初始化实例的运维或实施;一类是 PHP 开发,需要把现有项目从 MySQL 切到达梦、或者新项目要连接达梦数据库。

1. 达梦 DM8 是什么,PHP 连它为什么要另做准备

先说结论:达梦数据库是国产关系型数据库,DM8 是现在用得比较多的版本。很多人第一反应是“它兼容 Oracle”,所以把连接 Oracle 的习惯搬过来就行,实际上没那么简单。如果你是从 MySQL 过来的,SQL 里写的反引号、auto_increment、limit这些语法,在达梦上大概率会报错;更贴近 Oracle 的写法是SEQUENCE、ROW_NUM、DUAL这些。所以不只是连接方式要重新准备,SQL 习惯也得跟着调整。

PHP 项目要连达梦,和连 MySQL 最明显的区别是:PHP 默认没有达梦驱动,mysqli、pdo_mysql都不认识它。你得先想清楚走哪条路连,再动手配环境。

1.1 达梦的实际应用场景

我这次遇到的情况是单位内部系统指定用国产数据库,原因不外乎自主可控、部署环境合规、预算有限几个方向。达梦在政府、金融、能源这些行业的存量项目里出现频率很高,尤其是一些原来跑在 Oracle 上的老系统,做去 O 改造的时候,很多会选达梦,因为它的 Oracle 兼容性做得好,迁移成本相对可控。

对 PHP 项目来说,达梦并不算特别常见的搭配,但不代表不能连。一个典型的场景是:后台管理系统或报表系统已经跑在 PHP + MySQL 上,因为采购要求要把数据库替换成达梦;或者新项目明确要求数据库用达梦,业务侧继续用 PHP 开发。这两种情况下,你要解决的问题都很类似:先让 PHP 能建立连接,再处理 SQL 兼容性,最后处理性能和运维问题。

1.2 PHP 侧可选的三条路:ODBC、PDO_ODBC、专用驱动

我把 PHP 连接达梦的方式梳理了一下,实际能用的大概有三条:

连接方式依赖适用场景
ODBC 原生函数unixODBC + php-odbc老项目、简单查询,代码改动直观
PDO_ODBCunixODBC + pdo_odbc新项目,统一用 PDO 开发
达梦专用 PHP 扩展安装包内随附或单独下载追求性能或官方支持,按文档装,依赖发行版

我最推荐的是 PDO_ODBC 加 unixODBC 的组合。原因很实际:PDO 是 PHP 社区通用接口,以后就算从达梦换回 MySQL 或换到 PostgreSQL,代码主结构不用推倒重来;ODBC 是达梦官方提供驱动的标准通道,兼容性有保障。专用扩展性能理论上更好,但有些 PHP 版本和扩展版本匹配比较挑剔,装完还得处理编译期问题,踩坑成本偏高。所以除非你拿到的安装包已经带了官方扩展包,否则先用 ODBC 把项目跑起来是性价比最高的方案。

2. Linux 安装前的准备:少做一步就要返工

安装达梦数据库本身不算复杂,但很容易在准备阶段出问题。我在安装时跳过了一些常规检查,结果后面初始化实例和连接的时候反复返工。

2.1 先确认操作系统、磁盘和内存

达梦对 Linux 发行版没有特别苛刻的绑定,我这次用的是 CentOS 系的服务器,直接跑 DM8 没问题。安装前至少确认三件事:

  • 系统架构是 x86 还是 ARM,下载对应的安装包,不要拿错了;
  • 内存至少预留 2GB 以上给数据库进程,别在只有 1GB 的小机器上跑生产;
  • /dm8安装目录和数据目录要有足够空间,建议数据盘单独挂载,日志和数据分开。

检查命令不需要多高级,几行就够了:

uname -m free -h df -h / cat /etc/redhat-release

还有人容易忽略磁盘校验:达梦安装包通常是 zip 包,解压后是一个DMInstall.bin文件。我之前遇到过解压到一半磁盘满了,文件缺了一半,后续执行时报各种奇怪的段错误。建议解压前先确认磁盘剩余空间,解压后再用du -sh看看文件大小是否和安装包说明一致。

2.2 创建专用用户和安装目录,别拿 root 当数据库管理员

达梦官方安装建议是创建一个专用系统用户,一般是dmdba,用户组叫dinstall。这么做不是形式主义,数据库进程如果直接跑在 root 下,一旦有安全漏洞,影响范围直接到系统层面;而且达梦的安装脚本和服务脚本对权限判断很敏感,用非 root 用户安装,后续报错反而少。

我使用的准备命令:

groupadd dinstall useradd -g dinstall -m -d /home/dmdba -s /bin/bash dmdba mkdir -p /dm8/data chown -R dmdba:dinstall /dm8

这里有一个细节:安装包解压后要给DMInstall.bin加执行权限,否则 root 执行会提示“权限不够”。另外建议把安装包放到dmdba有权限的目录下,再用su - dmdba或者直接 root 执行安装,达梦安装程序本身会引导你创建目录。

2.3 License、环境变量和文件限制

安装前还要准备达梦的授权文件。如果是从官方渠道拿的安装包,通常会附带演示 key 或正式 key 文件。正式部署时不要把试用 key 随便放上去,影响的是后面实例的并发限制和一些高级功能。安装过程中会让你输入 key 文件路径,找不到的话也能跳过,但实例初始化后可能处于“未授权”状态。

另外,前面创建好dmdba用户后,建议把环境变量写进用户配置里,省得每次切用户都要手动 export:

cat >> /home/dmdba/.bash_profile << EOF export PATH=/dm8/bin:\$PATH export LD_LIBRARY_PATH=/dm8/bin:\$LD_LIBRARY_PATH EOF

LD_LIBRARY_PATH很关键,达梦的命令行工具依赖自己目录下的动态库,环境变量不设置,disql一运行就报找不到.so文件。最后还要把dmdba的ulimit -n调大一点,建议至少在 65536 以上,避免高并发时“Too many open files”。

3. 命令行安装达梦并初始化一个实例

服务器没有图形界面,一路./DMInstall.bin -i交互式安装。整个过程信息量不大,但每一步的选择会影响后面连接和性能,我说说我这次选的。

3.1 执行安装脚本到底选了些什么

安装命令很简单,在解压目录下执行:

./DMInstall.bin -i

安装程序会让你选语言、key 文件、时区,然后进入组件选择界面。如果没有特殊要求,我建议全选组件。数据库软件体积不大,少装几个组件省不了多少空间,但后面真要用某个工具时,再回去补装很麻烦。

安装路径我填了/dm8。这里有个容易忽略的点:安装路径不要带空格,不要放在/root下,否则服务脚本和 PHP 扩展开启时都容易碰到权限问题。安装到自定义路径,比如/dm8,后面处理起来清爽很多。

安装结束后,终端会提示你要用 root 用户执行一个脚本,路径通常在/dm8/script/root/下面。这一步不能跳过,它负责把数据库的启动服务注册到系统里,还会处理一些目录权限。我当时就是因为没执行这个脚本,后面systemctl里根本看不到达梦服务,白白折腾了半天。

3.2 用 dminit 初始化实例,参数影响性能和字符集

安装完成只是把软件放到了磁盘上,真正的“建库”工作由dminit完成。切换到dmdba用户,执行:

su - dmdba cd /dm8/bin ./dminit PATH=/dm8/data DB_NAME=DAMENG INSTANCE_NAME=DMSERVER \ PAGE_SIZE=16 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=Y \ PORT_NUM=5236

参数解释一下:

  • PATH:数据文件目录,初始化后实例文件都在这里;
  • DB_NAME:数据库名,我习惯叫DAMENG;
  • INSTANCE_NAME:实例名,后面注册服务时会用到;
  • PAGE_SIZE:页大小,可选 8、16、32,单位 KB。一个 Page 越大,单行能容纳的数据量越大,但空间浪费也更多。生产环境建议 16KB 起步,不要随便选 8KB;
  • CHARSET:字符集,1是 UTF-8,0是 GB18030。这个参数后期很难改,建议统一用 UTF-8;
  • CASE_SENSITIVE:大小写敏感。达梦默认对标识符大小写敏感,如果你是从 MySQL 切过来的,表名字段名的大小写习惯可能要变。接入历史系统时要特别留意;
  • PORT_NUM:数据库端口,默认 5236。

初始化成功后,输出里会显示实例路径、控制文件路径等信息。记下这些路径,后面启动服务和排查问题都要用。初始化之后系统会提示SYSDBA的默认密码,我强烈建议首次登录后立刻修改,不要拿默认密码上生产。

3.3 注册服务、启动数据库并用 disql 自检

初始化实例后,数据库还没有跑起来。达梦提供了服务注册脚本,安装目录下能找到类似/dm8/script/root/dm_service_installer.sh的脚本,root 用户执行:

/dm8/script/root/dm_service_installer.sh \ -t dmserver \ -p DMSERVER \ -dm_ini /dm8/data/DAMENG/dm.ini

注册成功后,服务名一般叫DmServiceDMSERVER。接着启动:

systemctl start DmServiceDMSERVER systemctl status DmServiceDMSERVER

如果 systemd 里看不到服务,可能是旧版本使用的 init 脚本方式,可以到/etc/init.d/下找对应的服务脚本,用/etc/init.d/DmServiceDMSERVER start启动。启动后用端口检查命令看是否监听:

ss -lntp | grep 5236

端口在监听后,再用达梦自带命令行工具检查一次连接:

disql SYSDBA/SYSDBA SQL> select name, create_time from v$database;

能查出数据库信息,说明实例没问题。这一步一定要做,因为后面 PHP 连接报错时,如果在达梦这一侧已经能通,就可以精准定位到 PHP 或 ODBC 配置上。

4. PHP 通过 ODBC 驱动连接达梦数据库,最省心的一条路

数据库装好只是开始,真正让 PHP 连上才是重点。我最后采用的是unixODBC + PDO_ODBC方案,完整流程分四步:装扩展、写驱动配置、测试连接、处理报错。

4.1 装好 unixODBC 和 PHP 的 ODBC 扩展

在 CentOS/RHEL 系统上,直接包管理安装,别急着编译 PHP。命令如下:

yum install -y unixODBC unixODBC-devel yum install -y php-odbc

unixODBC-devel一定要装,php-odbc在编译或安装时依赖它头文件。如果 PHP 是源码编译安装的,需要重新编译并加上--with-pdo-odbc=unixODBC,这种场景我遇过几次,建议先在老环境上跑php -m | grep -i odbc确认扩展是否存在。

装完扩展后,检查php.ini里是否启用了这几项:

extension=pdo_odbc extension=odbc

如果对应扩展.so文件已经放在扩展目录下但没启用,手动加一行再重启 PHP-FPM:

systemctl restart php-fpm

实际上,用发行版自带的php-odbc包时,/etc/php.d/下一般能自动生成odbc.ini文件,重启服务后php -m就能看到PDO_ODBC和ODBC。

4.2 配置 odbcinst.ini 和 odbc.ini,把驱动位置告诉系统

这是最容易出错的一步。达梦安装包本身带了 ODBC 驱动,一般放在安装目录的drivers/odbc下。我这边安装目录是/dm8,驱动文件路径大致是/dm8/drivers/odbc/libdodbc.so。不同版本文件名可能不一样,找一个又快又准的办法:

find /dm8 -name "*odbc*.so"

找到.so文件后,编辑/etc/odbcinst.ini,写入:

[DM8] Description=DM8 ODBC Driver Driver=/dm8/drivers/odbc/libdodbc.so

再编辑/etc/odbc.ini,这个是 DSN(数据源)配置:

[DM8] Description=DM8 Database Driver=DM8 Server=127.0.0.1 Port=5236 Database=DAMENG

我强烈建议先不要急着写 PHP,用命令行工具isql测一下 DSN 是否通了:

isql DM8 SYSDBA '你的密码' -v

如果isql能进入 SQL 提示符并执行查询,说明 unixODBC 和达梦驱动都没问题,问题只会出在 PHP 侧。我踩过最典型的一个坑是:odbcinst.ini里Driver写成了相对路径,isql一直报找不到驱动,改成绝对路径后立刻通了。

4.3 PDO 和原生 odbc_connect 连接示例

配置完 DSN 后,PHP 连接代码非常简单。PDO 方式:

<?php $dsn = 'odbc:Driver={DM8};Server=127.0.0.1;Port=5236;Database=DAMENG;UID=SYSDBA;PWD=your_password'; try { $pdo = new PDO($dsn); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->query('SELECT SYSDATE FROM DUAL'); var_dump($stmt->fetch(PDO::FETCH_ASSOC)); } catch (PDOException $e) { echo '连接失败: ' . $e->getMessage(); }

原生 ODBC 函数方式:

<?php $conn = odbc_connect('DM8', 'SYSDBA', 'your_password'); if (!$conn) { exit(odbc_errormsg()); } $res = odbc_exec($conn, 'SELECT * FROM v$database'); while ($row = odbc_fetch_array($res)) { print_r($row); } odbc_close($conn);

这段代码里用了DUAL表,是故意保留的。达梦对 Oracle 兼容性很好,查当前时间用SYSDATE FROM DUAL基本不会出问题。如果是新项目,可以建一张用户表,用INSERT和SELECT各验证一遍,看看达梦处理时间类型和自增主键的具体行为。

4.4 PHP 连接达梦的常见报错和解法

我把这次和之前遇到过的错误整理成了一份速查表,按优先级排查:

报错现场真正原因处理办法
Driver not foundodbcinst.ini 驱动路径错误用绝对路径,重启 PHP-FPM
[unixODBC][Driver Manager]Data source name not foundodbc.ini 里没有对应 DSN检查/etc/odbc.ini文件名和入口
invalid connection string attributePHP 连接字符串格式不对检查大括号、分号和UID/PWD是否齐全
Connection timeout达梦服务没启动或端口不通先查ss -lntp和数据库状态
User Id/Password invalid用户名或密码错误,或大小写问题用isql测一次,确认密码字符
PHP Fatal error: Uncaught PDOException: could not find driverPHP 没有启用 pdo_odbcphp -m查看扩展,修改 php.ini

这里我想强调一个排查思路:遇到连接问题,先定“层”。用disql测数据库层,用isql测 ODBC 层,用 PHP 脚本测应用层。哪一层先通,就知道问题在哪一层。不要一上来就在 PHP 代码里反复改连接串,效率极低。

5. 连上之后最容易踩的坑:编码、事务与账号权限

数据库连通只是第一步,把 PHP 项目真正跑起来又会冒出几个新问题。这几个坑我在实际迁移时都踩过,特意拎出来讲。

5.1 字符集一定要在初始化时定好,不然中文全变问号

达梦的字符集在dminit时就已经确定了,后期改非常痛苦。如果你的数据库初始化时选的是GB18030,而 PHP 项目统一是 UTF-8,查询结果里的中文大概率会乱码。乱码表现分两种:一种是在终端里正常,在 PHP 页面里乱;一种是数据库写入时就变成了问号,读出来也是问号。

处理原则是:

  1. 初始化实例时优先用CHARSET=1(UTF-8);
  2. 如果库已经建好,保持应用层和数据库层字符集一致,尽量“入库前统一转 UTF-8”;
  3. ODBC 连接串里能传字符集参数就传,例如Charset=UTF8;
  4. 实在改不了的,PHP 侧用iconv或mb_convert_encoding兜底,但这种方案不推荐。

有一类经典翻车现场是:数据库表字段定义的是VARCHAR2,PHP 写入的数据在插入前已经把中文转成了 UTF-8,但达梦实例字符集是 GB18030,导致长度校验直接报错。这种问题不是连接层能解决的,只能从建库参数上根治。

5.2 事务和 SQL 习惯别按 MySQL 来写

达梦支持事务,语法上更接近 Oracle。如果你习惯了 MySQL 的INSERT ... ON DUPLICATE KEY UPDATE、AUTO_INCREMENT、反引号包裹字段名,到了达梦会很别扭。我建议连接达梦的 PHP 项目,统一用标准 SQL 风格:

  • 主键值用序列或应用生成,不要指望AUTO_INCREMENT;
  • 分页不要用LIMIT offset, count,改用达梦支持的SELECT ... LIMIT?实际上达梦兼容性在不同版本有差异,最稳的是用 Oracle 风格的ROWNUM或窗口函数;
  • 字符串拼接用||,不要用CONCAT一个个嵌套;
  • 字段名不要加反引号,必要时用双引号。

事务处理上,PDO 的beginTransaction()/commit()/rollBack()是通用的,可以继续用。但如果用原生odbc_connect,默认自动提交行为可能和 MySQL 不同,我习惯在长事务里显式控制:

odbc_autocommit($conn, false); odbc_exec($conn, 'UPDATE ...'); odbc_commit($conn);

这一条在数据一致性要求高的业务里一定要测清楚,别等上线后发现部分更新没提交。

5.3 应用账号不直接用 SYSDBA,权限要收敛

很多人在本机测试时图省事,直接用SYSDBA连库,这在开发环境可以,但生产环境最好创建单独的应用账号。SYSDBA的权限太大,一旦 PHP 代码被注入,数据库的损失不可控。

达梦创建用户的语法和 Oracle 接近,大概类似:

CREATE USER app_user IDENTIFIED BY "YourStrongPass123";

然后按业务需要授权:

GRANT SELECT, INSERT, UPDATE, DELETE ON owner_name.t_user TO app_user;

很多新手管理员喜欢直接执行GRANT DBA TO app_user,千万别这么干。做数据库对接时,给出的 PHP 配置里至少做到:应用账号只能访问业务 Schema,不能操作系统表,不能修改实例参数。这样即使连接串泄露,影响面也小得多。

6. 这次安装运维我额外想提醒的几件事

最后这部分是我实际操作中觉得“如果早知道就好了”的经验,不一定每个项目都用得上,但值得记一下。

6.1 安装日志和 root 脚本很关键

达梦的安装日志、启动日志都很有用。安装目录下一般能找到log目录,数据库启动故障时,先去看日志,不要猜。我遇到过一次dmserver启动后立刻退出,报错信息很模糊,最后看日志才发现是数据目录权限没给到dmdba用户。

另外,安装完成时提示执行的那些 root 脚本,不是“建议执行”,是“必须执行”。脚本会注册服务和调整系统服务权限。跳过这一步,后面用systemctl管理数据库会变得非常别扭,所以我建议在执行安装前先看一眼安装日志里的 root 脚本路径,装完顺手执行掉。

6.2 备份和恢复工具要提前演练

达梦自带逻辑备份工具,名称很像 Oracle 的exp/imp,对应的是dexp和dimp。不要等到数据出问题才第一次用。我在项目上线前做了一次演练,大致命令如下:

# 在 dmdba 用户下执行,FULL=Y 表示全库导出 /dexp SYSDBA/你的密码 FILE=/bak/dm_backup.dmp LOG=/bak/dm_backup.log FULL=Y

恢复时用dimp对应导入。除了逻辑备份,达梦还有物理备份工具dmrman,适合做一致性备份和增量备份。生产环境建议至少有一套物理备份策略,不要只靠导出。

6.3 PHP 连接参数里的超时和错误模式别忘了配

很多 PHP 连接达梦的失败,不是连不上,而是连接后等待太久或者错误处理不到位。我给连接代码加了两项配置之后,排错效率明显提升:

$pdo->setAttribute(PDO::ATTR_TIMEOUT, 5); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

ATTR_TIMEOUT能让 PHP 在数据库假死或网络不通时快速失败,而不是卡在默认等待上。ERRMODE_EXCEPTION让每个 SQL 错误直接抛异常,配合日志记录,问题发生后能快速定位到具体 SQL 语句,而不是在页面上一片空白。

最后留一个我自己的习惯:我第一次连接达梦时,先用isql验证驱动和 DSN,再走 PHP。这样可以很干净地区分是数据库问题、ODBC 问题还是 PHP 配置问题。先把isql DM8 SYSDBA '密码' -v跑通,PHP 那边基本就是改几个参数的事。如果照做一遍还卡住,优先检查服务状态和odbcinst.ini、odbc.ini这两个文件,90% 的坑都在这。

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

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

立即咨询