用了多年通用数据库突然接到一整套“国产数据库技术”课程配套达梦 DM8 的学习任务时我第一反应其实是有点不屑的。毕竟习惯了成熟生态的外来数据库总觉得国产库大概率就是改个壳、抄点语法。真正啃完这套《国产数据库技术》的全程笔记自己动手把 DM8 从安装、建库、SQL 适配、应用接入一直到备份恢复全部走了一遍之后我必须承认之前那种预判多少带点偏见。达梦 DM8 在架构上是完整的关系型数据库并且在 Oracle 兼容性上花了大功夫同时在 MySQL 迁移、运维工具链、高可用方案上都有可落地的东西。本文就是我从零开始摸 DM8 的完整记录把每一个决策背后的逻辑、踩过的坑、可以直接照抄的命令全部整理出来给正在评估国产数据库或者要接手 DM8 项目的同行一个真实参考。无论你是 DBA、后端开发还是技术选型负责人这套笔记应该都能帮你少走几天弯路。1. 先看全局达梦 DM8 到底是什么样的数据库1.1 自研内核但兼容性做了双轨很多人的疑问是第一位的达梦 DM8 到底是自己写的还是基于某个开源分支改的我在学习过程中查了不少架构资料从官方技术白皮书和实际安装后的文件结构来判断DM8 的底层执行引擎、存储管理、事务处理都是独立实现不是 MySQL 或者 PostgreSQL 的分支产物。这个判断层面的问题很重要因为它决定了后续所有操作的思维方式。如果是基于开源库做的二次开发那我用开源社区的经验就能直接套但 DM8 不是所以它的初始化工具、配置文件、系统视图、备份命令等都有自己的一套命名和逻辑。比如它没有 MySQL 那种my.cnf而是用dm.ini作为实例配置文件默认端口是5236管理工具有独立的manager图形界面和disql命令行工具。这些都是自成一体的体系。但兼容性方面它确实参考了主流数据库的生态习惯。官方文档里明确提到兼容 Oracle 语法和 MySQL 语法两种模式实际体验下来Oracle 模式的完成度明显更高。很多 PL/SQL 风格的包、存储过程、数据类型在 DM8 里能找到对应物这对从 Oracle 迁移过来的团队极其友好。MySQL 模式更多是提供一些常用函数的别名和系统行为上的模拟毕竟 MySQL 生态也有大量用户。1.2 它适合放在什么场景里学完整个课程我对 DM8 的定位有了自己的判断它不是想在所有场景里跟主流数据库硬碰硬而是重点解决“基础软件供应链安全”环境下政企、金融、电力、制造等行业的核心业务替换需求。这些场景有个共同特征并发事务量大、数据一致性要求高、需要严格的权限管控和审计能力。DM8 的行级锁、MVCC 机制、完备的备份恢复体系、支持共享存储集群都是冲着这些需求设计的。如果你只是做一个个人博客或者小网站那它确实没必要但如果你面对的是一个需要固定预算内完成国产化替代的正式项目DM8 是非常现实的选择。我学习时的判断框架是先看它能不能把原业务平滑接住再看运维和学习成本能不能承受。答案是在兼容层做得足够好的前提下DM8 的上手难度并没有想象中高尤其是有 Oracle 经验的人适应周期会非常短。1.3 目录结构与关键进程安装完 DM8 之后有件事建议第一时间做把安装目录结构和进程关系搞清楚。以我用的 Linux 环境为例默认安装目录是/opt/dmdbms。/opt/dmdbms/ ├── bin/ # 可执行文件包含 disql、dmserver、dmrman 等 ├── data/ # 默认数据文件目录包含实例目录 ├── dm.ini # 默认实例配置文件 ├── log/ # 日志目录 ├── tool/ # 管理工具dmmanger、dmmonitor 等 └── web/ # 部分图形工具使用启动实例时核心进程是dmserver它会读取dm.ini里的参数完成初始化。整个数据库实例和一个操作系统进程强绑定这点要记住因为做启停操作的时候经常会需要用到进程管理命令来确认状态。我习惯用ps -ef | grep dmserver来快速判断实例是否正常。提示DM8 对目录权限比较较真尤其是数据目录如果使用非 root 用户安装务必保证该用户对数据目录有完整权限否则启动时会报各种奇怪的权限错误。2. 环境搭建与初始化把第一个实例跑起来2.1 安装前的前置检查我在这步踩过一个典型的坑没检查系统依赖库就开装结果图形界面起不来只能重新补包。在 Linux 上安装 DM8需要先确认几个基础条件操作系统架构x86_64 还是 ARM不同架构要下载对应安装包。内存建议至少 2GB 可用磁盘预留 10GB 以上因为安装包本身和解压后的文件都不小。需要 glibc 等基础库如果是精简版系统建议用ldd检查一下安装盘里的可执行文件依赖是否齐全。另外官方有图形安装、命令行安装和静默安装三种方式。我在虚拟机里第一次用的是图形安装毕竟交互性强适合学习真正要批量部署的时候静默安装才是王道。2.2 静默安装其实更实用图形安装没什么好说的下一步下一步就行。静默安装的好处是参数化、可重复适合以后在多台机器上部署。官方提供了一个配置文件模板我按照模板改了关键路径和端口后执行./DMInstall.bin -q /path/to/install_conf.xml配置模板里核心是这几个参数INSTALL_PATH/opt/dmdbms/INSTALL_PATH INSTALL_TYPEDATABASE/INSTALL_TYPE PORT5236/PORT DB_NAMEDAMENG/DB_NAME DB_INSTANCE_NAMEDMSERVER/DB_INSTANCE_NAME SYSDBA_PWDSYSDBA001/SYSDBA_PWD注意这里的SYSDBA_PWD是数据库超级管理员密码不是操作系统密码。安装完成之后一定要立刻改默认密码这属于最基本的安全习惯课程里反复强调实际生产也是如此。注意静默安装完成后默认会创建一个名为 DAMENG 的数据库实例初始化参数是默认的。如果你对页大小、字符集有特殊要求后面建库时要用工具重新创建实例。2.3 初始化实例的关键参数选择DM8 的实例创建可以用图形化的“数据库配置助手”也可以用命令行。我更推荐命令行方便记录和复现。初始化实例时有两个参数必须提前想清楚因为建库之后很难修改第一个是PAGE_SIZE页大小。DM8 支持 4K、8K、16K、32K 的页大小。页大小会直接影响单行最大长度、表空间文件最大大小以及数据库的整体 I/O 行为。默认 8K 对绝大多数业务是合适的但如果你的业务涉及大字段、超长字符串建议直接上 16K。我在模拟项目 X 里因为一开始用了默认 8K后面设计表时发现某些 VARCHAR 长度组合放不下只能重建库非常折腾。第二个是字符集。DM8 默认是 GB18030这是在中文 Windows 等环境下的老传统但对现代业务来说UTF-8 是更通用且避免乱码的选择。我建议直接选UTF-8。命令行方式创建实例如下cd /opt/dmdbms/bin ./dminit PATH/opt/dmdbms/data DM_INI/opt/dmdbms/data/DAMENG/dm.ini \ PAGE_SIZE16 CHAR_CODEUTF8 CASE_SENSITIVE0这里我额外设置了CASE_SENSITIVE0意思是标识符大小写不敏感。这个参数很影响使用体验。默认情况下 DM8 是大小写敏感的如果你从 MySQL 迁过来表名字段名习惯用大写或者小写很容易被这个坑到。对大多数业务应用关掉大小写敏感会更顺手。2.4 服务注册与启停初始化完成后需要把数据库注册成系统服务或者至少知道怎么手动启停。手动方式最简单直接调dmservercd /opt/dmdbms/bin ./dmserver /opt/dmdbms/data/DAMENG/dm.ini前台运行的方式适合调试因为日志会直接打到终端能第一时间看到启动错误。确认正常后我习惯注册成服务用项目里提供的脚本cd /opt/dmdbms/script/root ./dm_service_installer.sh -t dmserver -p DMSERVER -dm_ini /opt/dmdbms/data/DAMENG/dm.ini之后就能用systemctl start DmServiceDMSERVER这类命令管理了。3. 用户的创建与权限体系迈过入门第一道坎3.1 DM8 的默认用户不能只会用 SYSDBADM8 安装后自带几个默认用户这是很多新手最容易懵的地方。默认用户里最重要是下面这几个用户名作用说明SYSDBA超级管理员拥有数据库几乎所有权限SYSSSO安全管理员管理安全策略、审计SYSAUDITOR审计员查看审计记录SYS系统用户持有系统表、字典SYSTEM系统用户部分系统对象我第一次学的时候习惯性拿 SYSDBA 开干所有事后来课程里特别提醒正式项目不能这么干。DM8 的三权分立设计本质是让 DBA、安全管理员、审计员角色分离避免一个人权力过大。虽然小项目不一定要分这么细但至少应该给应用建独立的业务账号而不是拿 SYSDBA 连接业务应用。建用户的标准操作CREATE USER app_user IDENTIFIED BY App123456; GRANT CREATE SESSION, CREATE TABLE TO app_user; GRANT SELECT, INSERT, UPDATE, DELETE ON schema_name.business_table TO app_user;3.2 表空间从创建到配额表空间是数据库存储的逻辑单位每个用户最好都指定默认表空间。我在课程中养成的习惯是一个业务域一个表空间数据文件独立这样后续做备份恢复的粒度会很清晰。CREATE TABLESPACE TS_APP DATAFILE /opt/dmdbms/data/DAMENG/TS_APP.DBF SIZE 2048 AUTOEXTEND ON NEXT 128 MAXSIZE 8192; ALTER USER app_user DEFAULT TABLESPACE TS_APP;这里要提醒一个细节DM8 表空间数据文件大小受页大小影响页大小 8K 时单个数据文件最大约 32GB16K 页时最大约 64GB。如果建库时就预期数据量很大直接选 16K 或 32K 页后面省心。3.3 角色与最小权限原则DM8 内置了几种常用角色比如DBA、RESOURCE、CONNECT。这些角色解决的是批量授权问题但我实际操作后强烈建议宁可多写几条GRANT语句也不要图省事直接给业务用户DBA角色。国产化项目通常对安全审计有要求最小权限原则既是规范也是自保。课程里有个生动的例子某项目因为给报表账号开了 DBA 权限后来排查数据问题时审计记录里分不清是谁动了表责任界定的麻烦远远大于临时授权的便利。4. SQL 实战从建表到业务逻辑迁移4.1 数据类型和建表习惯DM8 数据类型整体上非常接近 OracleNUMBER、VARCHAR2、CLOB、BLOB都能直接用。同时它也支持 MySQL 风格的类型写法比如INT、VARCHAR。这给迁移带来了极大的方便但也会造成一个问题相同名称的类型底层行为可能不完全一致比如VARCHAR的默认长度单位、是否支持 0 长度等。我建表时采用的策略是从 Oracle 迁移的表保持原类型不动从 MySQL 迁过来的表全部统一改成 DM8 的 Oracle 风格类型。虽然前期要花点时间做转换但这能避免后续 SQL 写法出现隐式行为不一致。一个典型的建表示例CREATE TABLE T_ORDER ( ORDER_ID NUMBER(18) PRIMARY KEY, ORDER_NO VARCHAR2(32) NOT NULL, CUSTOMER_ID NUMBER(12), ORDER_AMOUNT NUMBER(12,2), STATUS CHAR(1) DEFAULT 0, CREATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP, REMARK VARCHAR2(500) ); CREATE INDEX IDX_ORDER_CUST ON T_ORDER(CUSTOMER_ID); CREATE INDEX IDX_ORDER_TIME ON T_ORDER(CREATE_TIME);注意DM8 的注释语句是COMMENT ON COLUMN T_ORDER.ORDER_NO IS 订单号;和 MySQL 那种行内COMMENT 订单号不同做迁移脚本的时候要转换。4.2 常用 SQL 写法差异对照这部分是干货中的干货。我把自己平时最常用的一些 SQL 写法在 DM8 和其他主流数据库之间做了对照功能MySQL/其他写法DM8 写法分页查询LIMIT 10 OFFSET 20SELECT ... LIMIT 10 OFFSET 20; 也支持 ROWNUM 写法字符串拼接CONCAT(a, b) 或当前日期NOW()SYSDATE 或 NOW()自增列AUTO_INCREMENTIDENTITY(1,1) 或序列触发器空值排序NULLS FIRST/LAST 取决于数据库默认 NULL 最大批量插入INSERT INTO ... VALUES (...), (...)支持多表值 INSERT也支持 INSERT ALL实际操作中分页查询我倾向于直接用LIMIT/OFFSET风格因为很多从互联网业务转过来的开发熟悉这种写法。但如果 SQL 已经用了 Oracle 的ROWNUMDM8 也兼容。4.3 存储过程迁移大头存储过程是 DM8 兼容性的主力战场。我建议拿一个真实的存储过程做测试比看十页文档都有效。以我测试的一个示例存储过程为例CREATE OR REPLACE PROCEDURE P_UPDATE_ORDER_STATUS( v_order_id IN NUMBER, v_new_status IN CHAR ) AS v_cnt NUMBER; BEGIN SELECT COUNT(*) INTO v_cnt FROM T_ORDER WHERE ORDER_ID v_order_id; IF v_cnt 0 THEN RAISE_APPLICATION_ERROR(-20001, 订单不存在); END IF; UPDATE T_ORDER SET STATUS v_new_status WHERE ORDER_ID v_order_id; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END;这个写法从 Oracle 迁移过来几乎不用改。DM8 支持RAISE_APPLICATION_ERROR、EXCEPTION、自治事务PRAGMA AUTONOMOUS_TRANSACTION等PL/SQL 的大部分能力都有对应实现。这也是为什么很多 Oracle 背景的项目选择 DM8 时存储过程迁移成本极低。4.4 数据装载与导出dmfldr 和 disql数据迁移绕不开批量导入导出。DM8 提供了图形工具“数据迁移工具”可以从其他数据库直接迁。但我的经验是大批量数据在场内做装载时用命令行工具dmfldr更高效。dmfldr的作用类似 Oracle 的sqlldr用法也很直白。假设我有一个/tmp/order_data.csv字段之间用逗号分隔cd /opt/dmdbms/bin ./dmfldr USERIDapp_user/App123456 CONTROL/tmp/load.ctl DATA/tmp/order_data.csv控制文件load.ctl内容示例LOAD DATA INTO TABLE T_ORDER FIELDS TERMINATED BY , TRAILING NULLCOLS ( ORDER_ID, ORDER_NO, CUSTOMER_ID, ORDER_AMOUNT, STATUS )这个工具我实测下来百万行级别的数据导入是分钟级比用图形界面或者逐条 INSERT 好了太多。导出方面dexp和dimp是逻辑备份导入导出工具类似于 Oracle 的exp/imp后面备份章节会说。5. 备份恢复与一致性DBA 能力的关键试金石5.1 备份方式全景DM8 的备份体系完整物理备份、逻辑备份都有。我建议按场景区分使用需求推荐工具说明数据库全量物理备份DMRMAN 或 disql 内 BACKUP 命令恢复速度快适合正式环境增量物理备份DMRMAN可以基于某个备份集做增量逻辑导出dexp适合迁移、小数据量逻辑备份逻辑导入dimp对应 dexp 的导入端物理备份推荐用DMRMAN工具这是 DM8 的备份恢复命令行工具功能比较全。做了全量备份和增量备份之后它能维护一个备份集恢复时可以基于这个备份集做完整恢复。5.2 备份实操记录我第一次做备份时图形界面点了几下就完事了后来发现命令行下更可控。全量备份命令如下cd /opt/dmdbms/bin ./dmrman CTLFILE/opt/dmdbms/data/DAMENG/dm.ini进入 dmrman 交互界面后执行BACKUP DATABASE /opt/dmdbms/data/DAMENG/dm.ini FULL BACKUPSET /backup/dm_full_20250101;这条命令生成一个全量备份集。增量备份则是在全量基础上执行BACKUP DATABASE /opt/dmdbms/data/DAMENG/dm.ini INCREMENT BACKUPSET /backup/dm_inc_20250102;增量备份必须指定在上一次备份之后执行DMRMAN 会自动追踪备份链。这里有一个踩坑记录备份路径所在文件系统剩余空间不够会导致备份失败而且 DM8 的报错提示信息在早期版本里不够直观只提示“磁盘空间不足”。所以做备份前先df -h检查磁盘是职业习惯。5.3 恢复流程把实例恢复到指定时间点恢复的思路是先还原数据文件再恢复日志或增量备份。用 DMRMAN 恢复到某个时间点的操作大致如下RESTORE DATABASE /opt/dmdbms/data/DAMENG/dm.ini FROM BACKUPSET /backup/dm_full_20250101; RECOVER DATABASE /opt/dmdbms/data/DAMENG/dm.ini FROM BACKUPSET /backup/dm_inc_20250102; RECOVER DATABASE /opt/dmdbms/data/DAMENG/dm.ini UPDATE DB_INFO;完整恢复流程的执行顺序很重要如果顺序反了DMRMAN 会报备份集不匹配可能还需要重新还原。我的练习方法是先备份然后往库里塞一堆测试数据再模拟删库最后完整走一遍恢复流程检查数据是否回到了备份点。这样整套流程跑顺之后心里才真正有底。5.4 高可用主备与共享存储集群课程里还简单介绍了 DM8 的高可用方案。主备架构下主库负责读写备库通过日志同步保持数据一致安装配置比裸跑实例复杂一些但核心思想并不难理解。做容灾演练的时候我学到最重要的一句话是“备份是最后一道防线高可用是缩短恢复时间的手段两者不能互相代替。”不管用主备还是共享集群日常备份都不能省。6. 实战中的疑难杂症与调优记录6.1 连接不上数据库先别急着怀疑密码我一共遇到过三次连接失败其中两次都是实例没起来。DM8 的dmserver进程崩掉或未启动时客户端会报“网络通信异常”但这容易让人误以为 IP、端口或者防火墙问题。排查顺序建议是ps -ef | grep dmserver ss -lntp | grep 5236先确认进程和端口都在再去检查连接串。这个顺序能省大量排查时间。如果进程死掉了去看实例目录下的日志重点搜ERROR关键字多半能直接定位问题。6.2 中文乱码字符集不匹配是元凶乱码问题在国产数据库课程里几乎必被提到。根源通常出在两端数据库字符集和客户端字符集不一致。我之前在 DM8 建库时选了 GB18030但应用端连接的字符集是 UTF-8插入中文后查询直接出乱码。解决方案有两种第一种最直接重建库时把字符集改成 UTF-8一劳永逸第二种是在 JDBC 连接串上指定encodingGBK或者UTF-8参数但这是治标不治本。涉及多套系统协作时标准做法就是全局统一 UTF-8。6.3 慢 SQL 分析与执行计划DM8 查看执行计划的方式和 Oracle 很像可以在 disql 里打开执行计划开关SET AUTOTRACE ON; SELECT * FROM T_ORDER WHERE CUSTOMER_ID 12345;也可以在 SQL 前加EXPLAIN关键字查看计划。我调优时最常用的几个方向确认索引是否被正确使用有没有发生不必要的全表扫描。确认条件字段的类型与索引字段类型是否一致类型隐式转换会导致索引失效。确认统计信息是否过期。DM8 在某些自动更新统计信息方面没有主流数据库积极大表数据量明显变化后我会手动执行DBMS_STATS.GATHER_TABLE_STATS(APP_USER, T_ORDER);来更新统计信息。一个真实记录生产环境某条查询之前毫秒级响应后来数据量涨了百倍后直接秒级。排查发现旧统计信息里表行数还停留在一万级别优化器选择了错误执行计划。分析后手动收集统计信息并重建了一个组合索引查询恢复到了 50 毫秒以内。6.4 内存参数调整DM8 实例的内存参数分成了很多池比如缓冲区BUFFER_SIZE、日志缓冲区等。最影响性能的一个是数据缓冲区BUFFER_SIZE。配置在dm.ini中修改后需要重启实例生效。我一般先看监控数据如果缓冲区命中率持续过低再逐步调大cd /opt/dmdbms/bin ./disql SYSDBA/SYSDBA001 SQL SELECT name, VALUE FROM V$PARAMETER WHERE NAME LIKE %BUFFER%;调整策略是让数据库整体缓冲区命中率保持在 95% 以上。如果命中率很低先别急着加内存可能更应该优化 SQL 和索引逻辑。7. 一些值得长期坚持的习惯整套课程学完我有一个很深的体会达梦 DM8 不缺功能缺的是使用者的心态转换。习惯了 MySQL 的人会觉得它部分系统表的写法别别扭扭习惯了 Oracle 的人又会拿它跟正版 Oracle 比较觉得这里不如那里不熟。但实际上评价一个国产数据库是否可用关键不在它与某一款数据库的相似度有多高而在于它在你具体的业务场景里能不能稳定、安全、可控地运转。我在学习后期的做法是把 DM8 当成一个独立产品来对待而不是某个数据库的仿制品。遇到不熟悉的语法先查官方手册遇到迁移问题先用小数据量测试遇到性能瓶颈认真分析执行计划而不是盲目加内存。数据库没有什么玄学所有问题最后都能落到架构、配置、SQL、数据分布这几个硬因素上。如果你正准备学 DM8我个人强烈建议把课程里每一个练习都动手操作一遍尤其是备份恢复和权限管理光看不练容易眼高手低。另外用达梦的迁移工具做一次真实的业务库迁移实验比看十篇对比文章都管用。这东西说到底就是个工具判断一个工具好不好拿起来干一把活最直接。
阅读完成 · 觉得有帮助?