
国产数据库这几年确实是技术圈绕不开的话题尤其是随着行业对自主可控的要求越来越高国产数据库从“能用”到“好用”的转变非常明显。我最近刚学完《国产数据库技术》这门课课程里花了大量时间在达梦数据库DM数据库的实践上。说实话没动手之前我以为这就是个“换皮Oracle”真正用下来才发现它确实在兼容上下足了功夫但也有很多自己的脾气和逻辑。这篇就把我这段时间从安装部署到实操踩坑的心得整理一下给正在学或者准备上手DM数据库的朋友做个参考。1. 达梦数据库整体认知它到底是个什么定位1.1 国产数据库赛道里的位置国产数据库现在大体分几派有从开源生态发展起来的比如基于PostgreSQL、MySQL内核二次开发的也有完全自主研发的。达梦属于后者它走的是“自主研发高度兼容Oracle”的路线。这个定位很聪明因为国内大量企业级系统以前跑在Oracle上数据库管理员和开发者的思维习惯都是Oracle那套如果能做到“上手即用”迁移成本就低很多。我在课程里第一次接触DM8的时候第一感觉就是命令行工具叫disqlSQL语法风格、数据字典视图比如DBA_TABLES、DBA_VIEWS、PL/SQL写法都带着浓厚的Oracle影子。但深入用下来你会发现在某些细节上它并不是完全照搬比如它的存储结构、表空间管理模式、备份恢复机制都有自己的一套设计逻辑。1.2 DM数据库的架构特点达梦的体系架构大体还是“实例数据库”的模式一个实例对应一个数据库实例由内存结构和后台进程组成。内存结构里比较核心的是缓冲池Buffer Pool、日志缓冲区Log Buffer、字典缓存等这些概念如果你熟悉Oracle就一点都不陌生。一个值得单独说的点是DM8的“模式Schema”和“用户”的关系。在达梦里创建一个用户时会自动创建一个同名的模式用户在默认模式下创建的表、视图都归属到这个模式。这一点和Oracle的行为一致但对于习惯MySQL里“库”和“用户”完全独立的人来说需要转换一下思路。这里有个实操中的小体会达梦的sysdba账号类似于Oracle的sys拥有最高权限日常开发尽量不要用它去连业务库建议单独建业务账号并授予必要的权限。我在做练习时一开始图省事全程用sysdba结果后面想测试权限控制相关的功能时还得回头重新建用户和授权增加了不少工作量。1.3 兼容性策略兼容但不等于替代课程里有一句话我印象很深达梦追求的是“兼容”而非“替代”。也就是说它努力做到让原来跑在Oracle上的应用能平滑迁移过来但不是所有Oracle高级特性都能直接一一对应。举个例子Oracle里有物化视图达梦8也支持Oracle有自治事务PRAGMA AUTONOMOUS_TRANSACTION达梦也有类似的实现。但有些冷门的内置函数、特定的包Package行为可能就需要手动调整。所以做迁移评估的时候不能只看业务能不能跑起来还要注意跑起来之后的性能是否达标、是否有隐藏的兼容性坑。我在课程实验里用达梦自带的迁移工具把一套模拟的学生选课系统从Oracle迁移到DM8表面上所有表结构和数据都迁过来了但实际跑存储过程的时候报了好几个错误都是因为某些Oracle特有的写法和内置函数在达梦里没有完全等价物。这也算是给所有做国产化迁移的人提个醒迁移工具能帮你搬运数据但代码层面的适配工作一点都不能偷懒。2. 安装部署实践从零到能连上数据库2.1 环境准备与安装包选择达梦数据库有企业版、标准版还有一个开发版个人学习用。课程里用的是开发版功能和标准版基本一致只是授权和性能上有限制。下载安装包之后解压出来是一堆rpm包和脚本这和Oracle那种巨型安装向导完全不同。我建议安装的时候注意几点用专门的用户比如dmdba来安装不要用root直接装这是个好习惯可以避免权限混乱也符合生产环境的规范。安装路径规划好不建议装到系统盘根目录因为数据库的数据文件会越来越大。disql这个命令行工具默认字符集可能和你的终端不一致中文显示乱码的话需要调整NLS_LANG相关的环境变量。有个同学在安装时没注意磁盘空间数据目录放到了根分区结果初始化实例到一半就报“磁盘空间不足”。这个看起来是很低级的错误但实际操作里确实不少人会踩到尤其是用虚拟机装的时候默认分配的磁盘往往刚够系统用根本没有冗余给数据库。2.2 初始化实例的“坑”安装完数据库软件之后还需要初始化实例。达梦初始化实例的工具叫dminit它会在指定目录下生成数据文件、控制文件、日志文件等然后才能启动数据库服务。初始化实例时几个关键参数要特别留意PAGE_SIZE页大小默认是8K如果业务里有大数据量的行可能需要设成16K或32K。这个参数一旦初始化后就不能改了必须提前想清楚。CHARSET字符集默认是GB18030如果你的应用主要是UTF-8建议在初始化时就指定为UTF-8。我自己第一次就没改后来为了调整这个参数折腾了很久。CASE_SENSITIVE大小写敏感这个参数决定了标识符大小写是否敏感。默认是敏感意味着你建表时写CREATE TABLE Test和CREATE TABLE test产生的是不同的表。对于从Oracle迁移过来的应用来说保持默认就好但如果你更习惯MySQL那种大小写不敏感的方式这个参数要提前改。我在初始化的时候周围好几个同学都遇到一个情况实例初始化成功了但用disql连接时报“登录密码错误”。后来发现是初始化时设置的密码里包含了特殊字符而终端环境的转义把密码搞变了。解决方法是初始化时暂时用简单密码等确认能登录后再用ALTER USER改成复杂密码。2.3 启动与连接检查实例初始化完成后启动服务有两种方式一种是注册成系统服务用systemctl管理另一种是直接用dmserver命令前台启动适合调试场景。我建议学习阶段用前台方式启动因为一旦数据库启动报错前台模式可以立刻看到日志输出方便定位问题。跑生产的话当然要注册成服务并且设置开机自启还要配置好自动重启策略。连接测试这一关除了用disql达梦还提供了图形化管理工具DM管理工具DM Management Tools。这个工具类似Oracle的SQL Developer可以图形化地管理用户、表空间、表结构、执行SQL脚本等。图形化工具对于初学者很友好至少比在命令行里懵着敲命令强但实际工作中很多DBA还是习惯写脚本毕竟批量操作的时候脚本效率高得多。有一个细节值得提一下达梦默认端口号是5236注意防火墙要放行否则远程连接不上。我课程实践里出现过自己本机可以连、但从另外一台虚拟机连不上的情况排查了半天最后发现就是虚拟机的防火墙挡了5236端口。3. 核心功能实践建库建表到数据处理3.1 创建表空间和用户达梦里创建表空间和用户的顺序和Oracle一致先建表空间再建用户并指定用户默认表空间。这里面有个关联逻辑表空间是存储数据的物理容器而用户模式是逻辑对象归属。实操里的标准流程大概是-- 创建表空间 CREATE TABLESPACE app_data DATAFILE /dm/data/DMDB/app_data.dbf SIZE 256M AUTOEXTEND ON NEXT 16M MAXSIZE 4G; -- 创建用户并指定默认表空间 CREATE USER app_user IDENTIFIED BY your_password DEFAULT TABLESPACE app_data; -- 授予基本权限 GRANT DBA TO app_user;这里要特别说明一下GRANT DBA TO app_user在学习环境里这么干图省事没问题但在生产环境绝对不能这样做。DBA角色权限太大了等于把整个数据库的钥匙都给了业务账号。正确做法是按需授权只授予业务实际需要的权限比如CREATE SESSION、CREATE TABLE、SELECT等。建表时达梦的数据类型和Oracle高度一致包括NUMBER、VARCHAR2、DATE、CLOB、BLOB等这让我从Oracle切过来的时候几乎没有学习成本。但如果你是从MySQL过来的可能会觉得NUMBER用起来不如INT直观其实本质上是一个东西就是定义方式不一样。3.2 SQL兼容性常用语句的差异体验我在实践里建了一个课程项目用的选课系统库里面包含了学生表、课程表、选课记录表还写了几个统计查询。达梦对标准SQL的支持很完整基本的JOIN、子查询、聚合函数、排序、分页都能用。有个分页查询的小差异特别值得注意。Oracle经典的分页写法是ROWNUMMySQL是LIMIT而达梦8直接支持LIMIT关键字同时也支持Oracle的ROWNUM。这意味着你可以用两种方式写分页非常灵活。但需要提醒的是LIMIT在达梦里不是所有场景都支持比如在某些子查询或视图定义里用LIMIT就可能报错这时候就要退回ROWNUM写法。再比如空值处理达梦默认行为和Oracle一样是“NULL不参与比较”这一点和MySQL的默认行为不同。如果你之前写惯了MySQL的查询在达梦里遇到数据查不出来先别急着怀疑SQL写错了很有可能是NULL处理逻辑不一样。还有一个实用小技巧达梦支持Dual表查询SELECT SYSDATE FROM DUAL;这个Oracle特性被完整保留了下来。3.3 存储过程和触发器PL/SQL风格的延续达梦的存储过程语法和Oracle的PL/SQL非常接近支持DECLARE、BEGIN、EXCEPTION、游标、存储函数、触发器等。课程里要求我们用存储过程实现一个简单的选课事务逻辑判断课程容量如果没满就插入选课记录并更新已选人数满了就抛出异常。我贴一段当时写的简洁版存储过程供大家感受语法风格CREATE OR REPLACE PROCEDURE sp_select_course( p_student_id IN VARCHAR2, p_course_id IN VARCHAR2 ) AS v_capacity NUMBER; v_selected NUMBER; BEGIN -- 查询课程容量和已选人数 SELECT capacity INTO v_capacity FROM course WHERE course_id p_course_id; SELECT selected_count INTO v_selected FROM course WHERE course_id p_course_id; IF v_selected v_capacity THEN RAISE_APPLICATION_ERROR(-20001, 课程容量已满); END IF; -- 插入选课记录更新已选人数 INSERT INTO enroll_record(student_id, course_id) VALUES (p_student_id, p_course_id); UPDATE course SET selected_count selected_count 1 WHERE course_id p_course_id; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END;这个写法如果之前写过Oracle的PL/SQL基本可以直接跑兼容度确实很高。但我在实际测试里发现达梦对RAISE_APPLICATION_ERROR的参数类型要求比较严格如果传进去的字符串长度超出限制会报错写代码时要注意控制错误提示信息的长度。触发器方面达梦支持BEFORE、AFTER、INSTEAD OF等类型语法和Oracle也基本一致。另一个细节是达梦的自治事务用PRAGMA AUTONOMOUS_TRANSACTION声明用于在触发器里写日志而不影响主事务的回滚。这和Oracle完全一样在实际项目里非常好用。3.4 视图与索引实践视图在达梦里用起来和Oracle一样支持创建普通视图和物化视图。我建了一个统计视图用于课程选课人数统计语句大致如下CREATE OR REPLACE VIEW v_course_stats AS SELECT c.course_id, c.course_name, COUNT(e.student_id) AS enroll_cnt FROM course c LEFT JOIN enroll_record e ON c.course_id e.course_id GROUP BY c.course_id, c.course_name;索引方面达梦支持B树索引、位图索引、全文索引等。在课程实践里我给选课记录表的student_id和course_id分别建了索引查询性能提升还是很明显的。经验是索引不是越多越好每个索引在加快查询的同时都会拖慢写入速度并且占用存储空间。要针对实际查询模式来设计索引用EXPLAIN看执行计划是最靠谱的判断方式。扩展一个实践心得达梦可以通过在SQL前面加EXPLAIN关键字来查看执行计划这一点和Oracle一致。执行计划能清楚地告诉你SQL有没有走索引、有没有做全表扫描是排查性能问题的最基本工具。我在调优一个选课统计查询时就是通过执行计划发现表连接顺序不对调整了驱动表和被驱动表的顺序后查询时间从十几秒降到了几百毫秒。4. 数据管理实操备份恢复与迁移4.1 备份机制的理解与操作达梦的备份分为物理备份和逻辑备份。物理备份备份的是数据文件本身恢复时能把数据库恢复到备份时刻的状态适合灾难恢复逻辑备份导出的是一系列SQL语句或记录适合数据迁移、异构数据库之间交换数据。我在实践中重点测试了物理备份和恢复达梦也有类似Oracle的归档模式概念。开启归档模式后数据库会保存所有事务日志这样在备份数据文件的基础上再应用日志可以把数据库恢复到任意时间点。实际操作里一个值得记录的点达梦在OPEN状态下做联机备份默认是备份数据库的完整数据文件加上归档日志这样才能保证恢复时数据一致性。如果只是简单备份了数据文件而没有备份归档日志恢复到某个时间点时可能因为日志缺失而失败。我测试恢复时印证了一个原则备份是一个完整流程里的其中一环备份后的验证也就是定期做恢复演练同样重要。课堂上我试了一次把数据库恢复到另一台机器上就因为两边安装路径不一致导致恢复失败后来通过修改dm.ini里的配置项才解决。这提醒我们生产环境里做恢复演练不能只在同一台机器上做跨机恢复必须提前验证环境差异。4.2 数据迁移工具的使用达梦提供了两个主要迁移工具一个是图形化的数据迁移工具DM数据迁移工具DTS一个是命令行工具dmfldr用于快速加载数据。我课程里先用了DTS把Oracle里的模拟数据迁到DM8整个过程界面引导清晰选择源库、目标库、映射表结构、开始迁移一气呵成。用DTS迁移时有几点实际经验值得分享迁移前要把源端的只读权限账号准备好避免使用高权限账号操作生产库。大表迁移时最好分批提交不然一个事务里数据量太大会消耗大量回滚段。字符集的坑非常容易出现。源Oracle库是AL32UTF8目标DM8设的GB18030的话迁移完成后中文乱码是必然的。所以在初始化DM库实例时就要确认好字符集方向不能迁移到一半再改。还有一个天然坑DTS并不能把Oracle里所有的存储过程、包、函数100%自动转换。我迁移完存储过程后用disql执行报了一些语法错误。这些不能指望工具自动处理只能手动修改函数名或语法。4.3 导入导出实践与数据一致性验证除了物理备份达梦的逻辑备份用dexp导出和dimp导入工具完成。类似的用法是# 导出某个用户的全部对象 dexp app_user/app_user_password DIRECTORY/dm/backup FILEapp_user.dmp LOGapp_user_exp.log # 导入到目标库 dimp app_user/app_user_password DIRECTORY/dm/backup FILEapp_user.dmp LOGapp_user_imp.log这里要注意导入时如果目标库里已经有同名对象通常需要先DROP或者使用忽略错误的参数否则会报“对象已存在”。我在实践时为了省事直接用了忽略错误的模式结果有些表虽然导入报告成功但数据量对不上一查发现是部分约束冲突导致数据没有完全导入。所以导入完成后的数据校验环节不能省略一定要通过COUNT(*)或者对比关键表的记录数来做验证。导入导出还有个经验大字段CLOB/BLOB多的表导出文件会非常大传输和导入都比较耗时。最好按照业务模块分用户、分表导出而不是一股脑全库导出这样既能减小单文件大小也方便单独恢复某个模块的数据。5. 常见问题与排查技巧记录这一块是学习过程中最有价值的沉淀。我把这段时间遇到的各种报错和解决办法整理成了一张速查表方便以后查阅。问题现象可能原因解决办法disql登录报“登录密码错误”密码含特殊字符被终端转义用简单密码初始化登录后ALTER USER改密码中文显示乱码字符集不一致初始化实例时设UTF-8/GB18030修改客户端NLS_LANG远程连不上数据库防火墙未放行5236端口开放端口核对监听IP是否为0.0.0.0LIMIT分页在视图中报错部分场景不支持LIMIT改用ROWNUM实现分页大表查询特别慢未走索引或执行计划有误EXPLAIN 查看计划优化索引设计存储过程报ORA-00942错误对象名大小写敏感或不存在确认大小写注意模式名schema前缀恢复备份到新机器失败路径不一致或控制文件找不到修改dm.ini里的路径参数保持目录结构一致导入数据后记录数对不上导入模式忽略了约束冲突导数据前先清理目标表或分批导入后验证COUNT排查问题时我发现达梦的日志体系分为事件日志和SQL日志默认情况下SQL日志可能没完全开启。当遇到奇怪的SQL问题而找不到线索时先检查是否开启了相关调试日志这会给你节省大量排查时间。另一个经常被初学者忽略的点是达梦的授权机制。开发版有连接数限制当多个终端同时连接时可能会报“超出许可连接数”这是正常现象不是数据库故障。宿舍几个人一起连着同一个数据库实验库练习的时候这个问题没少见。控制好连接复用或者轮流操作就可以避免这个报错。还要补充一个关于大小写的细致问题。我在某次实验中建了一张表叫Student因为大小写敏感参数开着后面写SQL的时候用了student小写直接报“表或视图不存在”。索引、列名、同义词的大小写也都要保持一致这在使用ORM框架时尤其要注意框架生成的SQL往往默认小写很容易踩坑。6. 个人实操总结与扩展思考6.1 学习路线上的体会学DM数据库给我的最大感受是它特别适合已经有一定关系型数据库基础的人快速上手。因为语法像Oracle管理理念也向Oracle靠拢所以只要你不是零基础几个小时就能完成建库、建用户、建表、导入数据这一整套操作。但对于只接触过MySQL的人有几点需要额外适应表空间和用户的关系需要理清既不是MySQL的“库”也不是完全孤立的“模式”。大小写敏感问题要提前确认不然SQL里到处是引号和大小写错误。数据字典视图从information_schema那套切换到达梦的DBA_*视图体系查询元数据的方式变得完全不同。我在实验里把之前用MySQL写过的一个简单的图书管理系统改造到了达梦上最初花了不少时间调试大小写和数据类型差异但调通之后整个改造过程反而变得很顺畅。这让我意识到达梦的Oracle兼容策略对国内大量存量系统来说确实是一条务实的路。6.2 后续可以继续挖掘的方向学完课程之后我觉得有几个方向值得继续深入达梦的集群部署和高可用方案比如数据守护、读写分离集群。单机学起来容易生产环境都是要上集群的而这方面我的实践还非常有限。性能调优。包括参数调整缓冲区大小、并发线程数等、SQL改写、索引优化这些和实际业务性能强相关也是DBA核心价值所在。异构数据库迁移的完整流程。课程里只做了一个模拟库的迁移真实场景里业务流程、存储过程、定时任务、应用代码的改造成本远比想象复杂。我个人体会是国产数据库的学习不能只在文档里看一定要亲手装一遍、建一遍、备份一遍、恢复一遍、报错一次再排查一遍这些经历里学到的东西才是真正能带到工作中去的。有一点心得想特别分享给刚开始接触达梦的朋友不要被“国产”两个字带着预设成见把它当成一个普通的、有自己特性的数据库产品去学习和使用。它的生态和工具链虽然不像国际老牌数据库那么庞大但在文档、社区、培训材料这些方面现在其实已经相当完整了。如果你所在的公司未来有国产化替代的计划现在动手学习达梦绝对是个划算的时间投入。