XXL-JOB接入达梦数据库:源码改造与MyBatis方言适配完整指南
做国产化适配那阵子接手的第一件事就是把 XXL-JOB 调度中心从 MySQL 迁到达梦数据库上。分布式定时任务这套东西整体逻辑不复杂真正磨人的是 XXL-JOB 这层皮它默认只对 MySQL 写死了建表脚本、分页语法和一批函数达梦数据库虽然打着 Oracle 兼容的旗号可真把官方 SQL 直接丢进去报错能铺满一整个屏幕。这篇文章我会把从达梦初始化、建表迁移、驱动替换、MyBatis XML 方言调整到编译打包的完整过程都写出来关键源码改动点会直接给代码追求的是照着做就能跑通而不是给你讲一堆云里雾里的理论。适合正在做信创改造、或者公司要求把任务调度底层换成国产数据库的读者参考。先说结论XXL-JOB 接达梦是完全可行的但你不要指望“复制粘贴”能一步到位核心工作量集中在调度中心 admin 模块的持久层适配执行器xxl-job-core根本不需要动。下面我按实际操作顺序把这一路踩过的坑都摊开讲。1. 背景XXL-JOB 默认只对 MySQL 友好达梦接入到底难在哪1.1 XXL-JOB 的数据层到底依赖了什么要搞懂迁移的痛苦来源先得知道 XXL-JOB 调度中心本身是怎么跟数据库打交道的。admin 端是一个 Spring Boot 应用持久层用的是 MyBatis里面管着任务信息、调度日志、执行器注册、用户、调度锁等一堆表我这次改造涉及的官方默认表有这些xxl_job_info定时任务配置主表xxl_job_log调度日志表数据量增长最快xxl_job_log_report调度报表统计表xxl_job_logglueGLUE 模式的代码存储表xxl_job_registry执行器注册表xxl_job_group执行器分组表xxl_job_lock调度中心集群互斥的锁表里面存的就是一把“调度锁”xxl_job_user后台登录用户表问题就出在这些表的 DDL 和 Mapper XML 全部是“MySQL 形状”的。比如官方建表脚本里有ENGINEInnoDB DEFAULT CHARSETutf8mb4、AUTO_INCREMENT、TINYINT(4)这种达梦完全不吃的东西Mapper XML 里又有大把的LIMIT #{offset}, #{pagesize}这种 MySQL 分页语法SQL 里还夹杂着NOW()、IFNULL()等 MySQL 专属函数。所以本质上不是“接不接得动”的问题而是“方言差异有多大”的问题。达梦虽然兼容 Oracle 语法默认案例也经常用 Oracle 模式但 XXL-JOB 这套 SQL 是照着 MySQL 写的所以你要做的是把整个持久层翻译成达梦听得懂的话。1.2 达梦兼容 MySQL纸上谈兵和实操是两回事达梦提供了兼容 MySQL 的初始化模式这点确实是真的。如果你在初始化实例时就选了“兼容 MySQL”很多常用语法比如LIMIT、NOW()、 反引号在达梦里是能直接用的。听起来是不是很简单但实际坑在别处。一是官方建表脚本除了方言语法还有字符集、引擎、索引定义这些东西工具导入的时候需要手工剥离大量 MySQL 专属关键字二是达梦的“兼容 MySQL”并不是 100%很多 MyBatis 动态 SQL 拼接出来的复杂语句照样会碰到不支持或者行为不一致的情况三是生产环境里不少达梦实例为了兼容已有的 Oracle 业务初始化时选的是 Oracle 模式这种情况下LIMIT直接就不能用了SQL 函数差异也更明显。坦白讲我建议不要在生产环境为了“少改代码”而去专门初始化一个兼容 MySQL 的达梦库除非你确定这个实例只给 XXL-JOB 用。更稳妥的做法是把实例参数搞清楚然后老老实实把 SQL 兼容改掉。1.3 改造前要把版本和环境定下来动手之前先把版本摸清楚。XXL-JOB 目前主流版本分两条线2.4.x 之前的老版本Mapper XML 里分页基本是写死LIMIT改起来要动的地方多一些3.x 版本官方做了一些方言抽象开始多了dbType或dialect相关的判断但对达梦仍然没有内置支持需要自己加枚举和分支。我这次在文档和示例里主要基于 2.4.0 讲同时会提 3.1.1 版本需要注意的差异点。你拿到源码后先不要急着改打开src/main/resources/mybatis-mapper/目录随便打开一个 XML搜一下LIMIT或者dialect就能判断自己手上的版本走哪种改法。另外准备好三样东西达梦的 JDBC 驱动包、一个能连达梦的客户端工具比如 DBeaver 或者达梦自带的 DM 管理工具、以及一台已经装好达梦的服务器Windows 或 Linux 都行Linux 上注意看达梦安装目录和端口默认 5236。2. 整体方案选型为什么我选了改源码编译2.1 三条改造路线对比接到这个需求后大致有三条路可以走我建议你先别急着敲键盘把方案摆出来比一比。第一条路是“数据中间层/代理转发”。也就是让 XXL-JOB 继续连一个“假的 MySQL”中间有个网关把 MySQL 协议翻译成达梦协议。好处是一行代码不用改坏处是中间件本身要部署要维护而且 MyBatis 动态 SQL、FOR UPDATE、事务边界这种东西经过一层翻译后很容易出幺蛾子出问题后你很难判断是调度中心的问题还是网关的问题。除非公司已经有统一的数据网关团队否则单项目引入这个属于给自己埋雷。第二条路是“只改配置期望达梦自动兼容”。达梦确实提供了兼容参数比如连接串里加compatibleModemysql但这只能解决一部分函数和语法问题。你连表结构都还没导进去呢官方 DDL 里的ENGINE、AUTO_INCREMENT、COMMENT这些东西会把导入直接卡住就算你用客户端工具把表建出来了分页和函数的问题依然在。这条路可以拿来“快速验证驱动能不能通”但撑不到最后。第三条路就是“改源码编译”。听起来有点吓人实际改动面非常可控主要就集中在xxl-job-admin模块的配置文件和 Mapper XML真正涉及 Java 代码逻辑的很少。改完之后自己维护一套内部版本后续升级官方版本时把改动 patch 过去就行。我们最终选的就是这条路理由很实在可掌控、无额外中间件依赖、符合信创项目里“源码可控”的审计要求。2.2 改造范围到底有多大很多人一听到“改源码”就慌我先把范围说清楚。整个 xxl-job 工程包含多个模块但你只需要动xxl-job-admin一个执行器模块xxl-job-core不需要碰因为执行器是通过 HTTP 和调度中心通信的不直连数据库。改造清单也很有数新增达梦 JDBC 驱动依赖pom.xml修改数据源连接配置application.properties迁移官方建表脚本为达梦版本sql 目录修改所有含 MySQL 方言的 Mapper XML 文件少量处理达梦下 Map 返回列名大小写问题看实际情况改动文件加起来也就十来个其中大头在 XML每个文件的差异就是分页和个别函数的写法。这不叫“魔改”叫“方言适配”。真正理解每一条 SQL 为什么那么写之后你会发现 XXL-JOB 的技术设计是相当克制的它没有用什么花哨的 SQL绝大部分就是常规的 CRUD、分页、统计和FOR UPDATE。2.3 带源码交付意味着什么这个项目标题里专门点了“带源码”我多说两句。在很多公司尤其是政企项目里交付物里面“源码可编译、可审计、可维护”是很重要的一条要求。光给一个改好的 jar 包运维没法验证领导不放心后续也没法扩展。所以我会建议你改完代码后保持标准的 Maven 工程结构把达梦的初始化脚本单独放到sql/dm/目录把改造说明写进 README最后打出来的包也用在源码根目录构建这样既方便自己归档也能直接作为交付物让对方自己跑一遍。源码改造不是“能跑就行”而是要让下一个接手的人一眼看懂改了哪里、为什么改。3. 动手第一步达梦实例初始化和建表脚本迁移3.1 实例初始化时最关键的几个参数达梦的安装过程本身不复杂Linux 下就是解压安装包然后执行DMInstall脚本Windows 下有图形化向导。容易出问题的不是安装而是初始化实例时那几个参数选错后面写 SQL 的时候能让你怀疑人生。最关键的参数是“大小写敏感”选项。达梦在初始化实例的时候会让你选大小写敏感还是不敏感这个参数一旦定了后面想改很麻烦。如果你选了“大小写敏感”那么不带引号的标识符会自动转成大写存储和匹配也就是说官方 XML 里写的小写表名xxl_job_lock实际访问的是大写表XXL_JOB_LOCK这在大多数情况下能自动对上但一旦某个 SQL 里用了双引号包裹小写表名就会出现“表或视图不存在”。我们项目里统一采用“大小写不敏感”模式然后建表脚本和 SQL 全部保持和官方一致的小写风格这样最省心。另外字符集建议直接选UTF-8别用默认的 GBK因为 XXL-JOB 的 GLUE 代码和任务描述里很可能有中文GBK 环境下稍不留神就是乱码。端口保持默认的 5236 就好实例名和库名你自己定我在示例里统一用XXL_JOB作为模式名Schema。注意达梦的“模式”和 MySQL 里的“数据库”概念不太一样。在达梦里一般是一个用户对应一个 Schema用 SYSDBA 登录时默认就能访问 SYSDBA 模式下的表。如果你想单独建一个业务用户建用户的时候达梦会自动生成同名 Schema这样业务表和系统表隔离会更干净。3.2 官方表结构迁移到达梦的通用改法拿到官方tables_xxl_job.sql之后不要傻乎乎地直接双击执行。我推荐的做法是在 DBeaver 里新建好连接后把官方脚本拆开逐段处理。MySQL 建表脚本里经常出现这些东西需要逐个处理去掉ENGINEInnoDB DEFAULT CHARSETutf8mb4这类建表尾巴AUTO_INCREMENT要替换成达梦的IDENTITY(1,1)TINYINT(4)把括号和宽度去掉写成TINYINT达梦根本不认识“显示宽度”行内注释COMMENT xxx在达梦的很多模式下不支持建议改成COMMENT ON COLUMN的形式或者干脆去掉DATETIME类型达梦支持可以保留DEFAULT CURRENT_TIMESTAMP在部分模式下有问题稳妥起见改成DEFAULT SYSDATE索引定义里的KEY关键字改成达梦标准的CREATE INDEX语句。拿最典型的xxl_job_lock表为例MySQL 官方脚本大概是这样的CREATE TABLE xxl_job_lock ( lock_name VARCHAR(50) NOT NULL, PRIMARY KEY (lock_name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;到达梦这边去掉反引号、引擎和字符集尾巴就是CREATE TABLE xxl_job_lock ( lock_name VARCHAR(50) NOT NULL, PRIMARY KEY (lock_name) );再比如xxl_job_info表里的自增主键和任务描述字段MySQL 写的是id INT NOT NULL AUTO_INCREMENT达梦就是CREATE TABLE xxl_job_info ( id INT IDENTITY(1,1) NOT NULL, job_group INT NOT NULL, job_desc VARCHAR(255) NOT NULL, add_time DATETIME NULL, update_time DATETIME NULL, author VARCHAR(64) NULL, alarm_email VARCHAR(255) NULL, schedule_type VARCHAR(50) NULL, schedule_conf VARCHAR(128) NULL, misfire_strategy VARCHAR(50) NULL, executor_route_strategy VARCHAR(50) NULL, executor_handler VARCHAR(255) NULL, executor_param VARCHAR(512) NULL, executor_block_strategy VARCHAR(50) NULL, executor_timeout INT NOT NULL DEFAULT 0, executor_fail_retry_count INT NOT NULL DEFAULT 0, glue_type VARCHAR(50) NULL, glue_source TEXT NULL, glue_remark VARCHAR(128) NULL, glue_updatetime DATETIME NULL, child_jobid VARCHAR(255) NULL, trigger_status TINYINT NOT NULL DEFAULT 0, trigger_last_time BIGINT NOT NULL DEFAULT 0, trigger_next_time BIGINT NOT NULL DEFAULT 0, PRIMARY KEY (id) ); COMMENT ON TABLE xxl_job_info IS 调度任务信息表;这里我故意只列了核心字段实际上把官方表全部迁移过来大概要花一两个小时。迁移完以后建议在 DBeaver 里逐表展开确认表名、字段名、主键、索引都在重点看xxl_job_log、xxl_job_registry这几个更新频繁的表的索引有没有建上。索引很关键xxl_job_log表如果没有索引跑几个星期之后调度日志查询会越来越慢。3.3 用 Navicat/DBeaver 连接达梦验证表建完之后先别急着改代码先用客户端工具确认连接没问题。DBeaver 连达梦需要在驱动管理里添加达梦驱动类名填dm.jdbc.driver.DmDriverURL 模板填jdbc:dm://{host}:{port}/{schema}。Navicat 新版支持达梦数据库如果列表里没有去官方下载连接达梦的版本。用 SYSDBA 登录之后执行一条最简单的查询SELECT 1 FROM DUAL;再看看刚才建表所在的模式执行SELECT TABLE_NAME FROM USER_TABLES;如果能看到XXL_JOB_INFO、XXL_JOB_LOCK这些表说明表和连接基本正常。这一步建议你顺便把达梦安装目录下的 JDBC 驱动 jar 拷出来Windows 一般在安装目录的drivers/jdbc/下面Linux 一般在/opt/dmdbms/drivers/jdbc/下面文件名一般是DmJdbcDriver18.jar或者DmJdbcDriver8.jar。这个 jar 后面编译打包要用先放到一个安全的位置。4. 动手第二步xxl-job-admin 源码改造细节4.1 引入达梦 JDBC 驱动打开xxl-job-admin模块的pom.xml找到原先的 MySQL 驱动依赖注释掉或者留着都行反正最终生效的是达梦驱动。我不建议把驱动 jar 传到 Maven 中央仓库也没这个必要直接在工程里放一个lib目录用systemscope 引用或者先安装到本地仓库再正常依赖。安装到本地仓库的命令是这样mvn install:install-file -Dfile/path/to/DmJdbcDriver18.jar -DgroupIdcom.dameng -DartifactIdDmJdbcDriver18 -Dversion8.1.3.62 -Dpackagingjar然后在 pom.xml 里加dependency groupIdcom.dameng/groupId artifactIdDmJdbcDriver18/artifactId version8.1.3.62/version /dependency如果你不想污染本地仓库也有更简单的做法直接放在模块目录下用system引用dependency groupIdcom.dameng/groupId artifactIdDmJdbcDriver18/artifactId version8.1.3.62/version scopesystem/scope systemPath${project.basedir}/lib/DmJdbcDriver18.jar/systemPath /dependency注意达梦驱动版本和 JDK 版本有关系JDK18 及以上用DmJdbcDriver18老 JDK8 环境用DmJdbcDriver8也行。如果启动时报驱动类找不到或者版本不兼容优先检查驱动 jar 有没有真正打进去。4.2 数据源配置的四个关键点打开xxl-job-admin/src/main/resources/application.properties数据源相关配置就这四行spring.datasource.urljdbc:dm://127.0.0.1:5236/XXL_JOB spring.datasource.usernameSYSDBA spring.datasource.password你的密码 spring.datasource.driver-class-namedm.jdbc.driver.DmDriverURL 里的/XXL_JOB指的是达梦模式名大小写和实际模式要一致如果你建的用户是XXL_JOB就填这个名字。驱动类名我见过新老两种写法老一点的是dm.jdbc.driver.DmDriver新版本驱动有的叫dm.jdbc.driver.DmJdbcDriver18具体看驱动包里META-INF/services或者官方文档两个都试一下就知道。XXL-JOB 的 admin 用的是 HikariCP 连接池达梦驱动兼容 JDBC4 的isValid()探活机制所以连接池这边基本不用额外配置。如果你在日志里看到频繁断连或者连接泄漏的报错再往连接池参数上查比如加一句spring.datasource.hikari.maximum-pool-size50这个值和后面调度任务量挂钩任务量大就调大默认值 10 对一般项目够用但信创环境下调度中心往往同时扛几百个任务我建议直接调到 50避免高峰期连接不够用。4.3 MyBatis 分页 SQL 的方言改写这是整个改造中工作量最大的一块。XXL-JOB 里分页查询集中在几个 Mapper 的pageList方法典型语句是这样的select idpageList resultMapXxlJobInfo SELECT include refidBase_Column_List / FROM xxl_job_info where if testjobGroup gt 0AND job_group #{jobGroup}/if if testtriggerStatus gt -1AND trigger_status #{triggerStatus}/if if testjobDesc ! null and jobDesc ! AND job_desc LIKE CONCAT(%, #{jobDesc}, %)/if /where ORDER BY id DESC LIMIT #{offset}, #{pagesize} /select如果达梦实例初始化时选了“兼容 MySQL”这里LIMIT大概率能直接用你甚至可以只改函数不改分页。但现实是很多达梦实例跑在 Oracle 模式下那LIMIT就废了要改成 Oracle 风格的分页嵌套也就是经典的 ROWNUM 三层查询select idpageList resultMapXxlJobInfo SELECT * FROM ( SELECT t.*, ROWNUM rn FROM ( SELECT include refidBase_Column_List / FROM xxl_job_info where if testjobGroup gt 0AND job_group #{jobGroup}/if if testtriggerStatus gt -1AND trigger_status #{triggerStatus}/if if testjobDesc ! null and jobDesc ! AND job_desc LIKE CONCAT(%, #{jobDesc}, %)/if /where ORDER BY id DESC ) t WHERE ROWNUM lt; #{offset} #{pagesize} ) WHERE rn gt; #{offset} /select这里有两个细节。第一MyBatis XML 里小于号和都要转义所以写lt;和gt;不转义直接写会导致容器启动报错。第二MyBatis 的#{}不允许在内部做算术所以#{offset} #{pagesize}这种写法在#{}里面是不行的我上面的写法实际是把${offset}和${pagesize}通过表达式拼进 SQL存在注入风险但 offset 和 pagesize 是从分页插件传进来的整数风险可控。如果你不想在 XML 里写算术表达式更规范的做法是在 Mapper 接口方法里多传一个 end 参数或者在 XML 里用bind标签bind nameendRow valueoffset pagesize/然后再把WHERE ROWNUM lt; #{endRow}这样写既安全又清晰。改完 XML 之后最好全局搜一下LIMIT关键字确认所有分页 SQL 都已经替换掉。我改的时候大概处理了 6 个 XML 文件主要是XxlJobInfoMapper.xml、XxlJobLogMapper.xml、XxlJobLogReportMapper.xml、XxlJobRegistryMapper.xml、XxlJobGroupMapper.xml这些。4.4 MySQL 专属函数怎么替换分页改完之后还有一类坑隐藏得很深函数兼容问题。XXL-JOB 的 SQL 里用到了一些 MySQL 风格函数达梦在 Oracle 模式下是不认的。我把常用的对照关系整理成了一张表你改 XML 的时候可以对着查MySQL 写法达梦推荐写法说明NOW()SYSDATE或CURRENT_TIMESTAMP取当前时间IFNULL(a, b)NVL(a, b)判空取默认值IF(a, b, c)CASE WHEN a THEN b ELSE c END条件表达式CONCAT(%, #{val}, %)CONCAT(%, #{val}, %)达梦有 CONCAT一般不用改DATE_FORMAT(d, %Y-%m-%d)TO_CHAR(d, YYYY-MM-DD)日期格式化UNIX_TIMESTAMP()视情况用SYSTIMESTAMP转换获取时间戳比如xxl_job_log_report的报表查询里如果有按月统计日期格式化这种需求原封不动用DATE_FORMAT在达梦里就炸了改写成TO_CHAR以后逻辑完全一致。还有一个特别容易忽略的点达梦里字符串连接如果某个字段是 NULLCONCAT的行为和 MySQL 不太一样拼接出来的结果可能直接变成 NULL所以 SQL 里涉及可能为空的字段拼接时建议先NVL(field, )再接不然 GLUE 任务的路由策略、执行器参数这些字段显示出来会莫名其妙丢数据。另外XXL-JOB 里有几条FOR UPDATE的锁语句比如集群调度时要锁住调度锁那一行。FOR UPDATE达梦是支持的不用改但要注意事务必须开启否则锁不住这个在源码里本来就是事务方法不需要你额外处理。5. 动手第三步编译打包、部署与全链路验证5.1 Maven 编译打包代码改完后进入编译打包阶段。XXL-JOB 整个工程是个多模块 Maven 项目直接用根目录的 pom.xml 构建mvn clean package -DskipTests如果你只想构建 admin 模块减少编译时间可以加参数mvn clean package -pl xxl-job-admin -am -DskipTests编译过程中如果报依赖错误八成是达梦驱动没有正确安装到本地仓库回 4.1 节重新确认一下。如果报 XML 解析错误基本就是 XML 里的、没转义打开对应文件检查一遍。构建成功后admin 的启动 jar 在xxl-job-admin/target/xxl-job-admin-2.4.0.jar版本号可能不同直接启动java -jar xxl-job-admin-2.4.0.jar理论上它的自动配置会去连达梦连不上会在日志里直接报数据库连接异常。看到以下日志基本就说明连接通了HikariPool-1 - Start completed.然后浏览器访问http://你的IP:8080/xxl-job-admin默认账号是 admin / 123456。能打开登录页并且能登录进去说明基础环境已经 OK 了。5.2 部署启动检查清单登录进去之后别急着建任务先过一遍检查清单确认每个页面不报错“执行器管理”页面能否打开、能否新增执行器“调度日志”页面能否打开、能否按条件查询“任务管理”页面能否打开、分页是否正常日志报表图表能不能加载注意这里最容易暴露 Map 字段大小写问题图表加载不出来或者全是 0 就要小心了。这些页面背后就是刚才改的那些 Mapper XML任何一个页面对应的 SQL 出了问题你都能在后台日志里看到具体的报错信息。比较典型的报错是“无效的列名”、“表或视图不存在”、“列名无效”这时候先别慌很大概率是大小写敏感策略导致的。如果确定是大小写问题最省事的解决办法是回到第一步用不敏感的实例重新初始化而不是一个个去改 SQL。5.3 任务调度全链路验证页面都通之后只算完成了一半关键在“跑任务”。我建议新建一个最简单的测试执行器然后添加两个任务一个用 Bean 模式执行器端写 Handler一个用 GLUE 模式在调度中心直接写代码分别手动执行一次。手动执行一次能通过再看调度日志里的“调度结果”和“执行结果”两列正常情况下应该是“成功”和“成功回调”。这里尤其要看执行结果因为调度中心只是把任务分发出去真正干活的还是执行器如果执行器没起来或者 handler 名写错调度结果没问题但执行结果会一直显示“调度失败”或者没有回调。集群场景也建议顺手验证一下启动两个 admin 实例指向同一个达梦库然后手动触发任务看两个实例是否只有一个能抢到调度锁另一个进入待命状态。这个靠的就是xxl_job_lock表和FOR UPDATE如果这里有问题多半是事务没生效或者锁表语句被改坏了。6. 常见问题排查与避坑速查表6.1 表或视图不存在的诡异报错这个问题我在迁移过程中遇到了好几次现象是某个页面查询时报表或视图不存在但明明用 DBeaver 能查到表。原因基本出在大小写处理上。达梦默认会把不带引号的标识符转成大写官方 XXL-JOB 的 XML 里写的是小写表名如果实例是大小写敏感模式那么实际访问的就是大写表只要建表时建的是大写表就能对上。怕就怕有人用 DBeaver 导表时因为配置原因建出了真实的小写表然后又试图用小写查询两边就拧巴了。各种奇怪的“找不到对象”错误基本都是这个问题。实践中最稳的策略是初始化实例时选择“大小写不敏感”建表脚本用官方原装小写XML 保持小写不动全链路统一。不要自己在某些地方加双引号强行保小写那只会带来更多混乱。6.2 自增主键和 ID 冲突问题建表时如果自增列没处理好最常见的问题是插入数据时报“重复键值”。XXL-JOB 的表里xxl_job_info、xxl_job_log、xxl_job_logglue、xxl_job_registry这些都有自增主键达梦里叫IDENTITY(1,1)。有一个细节容易遗漏如果你是从 MySQL 迁移数据过来把老数据连同 ID 一起 insert 进去那么自增列的值可能不会自动跳到最大 ID 之后后面再插入就冲突了。达梦里IDENTITY列默认是不允许显式插入值的如果你确实要带 ID 导入要么临时用SET IDENTITY_INSERT 表名 ON要么干脆导完数据后重置自增起点。如果是全新部署根本没有老数据那就不存在这个问题。6.3 Map 返回结果 key 大小写导致取不到数据XXL-JOB 里有几个查询是把结果直接映射成MapString, Object返回的最典型的就是日志报表。在 MySQL 里MyBatis 拿到的列别名是什么Map 的 key 就是什么但达梦 JDBC 驱动在某些版本里会把列名转成大写。比如 SQL 里写了COUNT(trigger_code) AS triggerDayCountMySQL 里 map.get(triggerDayCount) 能取到值到达梦上可能就变成 map.get(TRIGGERDAYCOUNT) 了代码里取不到就返回空或者默认为 0报表页面就会显示不出来或者全是 0。排查思路很简单后台日志或调试时打印一下返回的 Map 的 key 集合看是不是大写。解决方式也直接把 SQL 里的别名改成双引号包裹的小写别名例如AS triggerDayCount达梦就会严格按引号里的名字返回。6.4 授权过期和连接不上的问题这个坑可能你们不一定遇到但达梦试用版确实很常见。达梦数据库有授权机制如果授权文件过期最典型的现象是数据库服务正常在运行DBeaver 也能连上但执行稍微像样一点的 SQL 就会报授权相关错误或者连管理工具都提示“试用期已过”。解决方法就是去达梦官方申请正式授权或延期授权然后把授权文件放到安装目录的对应位置重新启动数据库服务。如果是 Docker 方式部署的达梦还需要把授权文件挂载到容器里否则重启就失效。这个不属于 XXL-JOB 本身的问题但排查数据库接入问题时容易被忽略遇到过好几回先检查这个能省掉不少时间。6.5 日志表膨胀与调度性能变慢跑了一段时间后你会发现xxl_job_log表体积涨得飞快尤其任务量大、调度频率高的场景一天几百万条日志很轻松。MySQL 里很多团队靠分区表来扛达梦同样支持分区表但 XXL-JOB 官方脚本没有自带分区。改到这一步的团队我建议优先做好两件事一是确认调度中心的日志保留天数配置xxl.job.logretentiondays真在生效XXL-JOB 本身有清理日志的后台任务默认好像只有几天但日志量大时清理会慢二是手动给xxl_job_log加上合适的索引尤其按任务 ID 触发时间查询的索引。如果清理和索引都做了还是慢可以考虑把日志表改成分区表按trigger_time做范围分区查询和清理都能走分区裁剪。达梦的分区表语法和 Oracle 类似改造工作量可控但那是另一个话题了我在这里只提醒一句别等日志表拖垮调度中心了再想起来维护。6.6 常见问题速查表问题现象可能原因解决方向启动时报驱动类找不到达梦驱动 jar 没打进包检查 pom 依赖和本地仓库页面报表或视图不存在实例大小写敏感策略和表名不一致实例配置选不敏感或者统一加双引号分页查询语法报错XML 里还有LIMIT全面替换为 ROWNUM 分页或兼容模式运行报表图全是 0Map 返回的列名大小写不一致SQL 别名加双引号保持小写插入数据报重复键自增列 IDENTITY 设置不对或导数据导致清空重置自增或正常方式插入连接超时/授权异常达梦授权过期更新授权并重启数据库查询越来越慢日志表膨胀、缺少索引配置日志保留天数、补索引、考虑分区表我在实际改造中最大的体会是不要把“兼容”想成“把 SQL 拷贝过去就能跑”。达梦的兼容性并不是差的代名词但它的环境参数、驱动版本、大小写策略每一个都会影响最终结果尤其是大小写模式选错了能让你在排查“表或视图不存在”上耗掉一整天。如果你们也在做信创适配建议把达梦的初始化参数、建表脚本和源码改动一起纳入配置管理不然换一台机器部署又得从零开始踩一遍。最后再分享一个小技巧改造完成后不要急着接业务真实任务。先把 XXL-JOB 自带的示例执行器在本地跑起来Bean 模式和 GLUE 模式各建一个任务把“调度-执行-回调-日志查询-报表展示”这条链路整体过一遍。看似简单的这个动作实际能把数据源配置、分页、函数、Map 返回这些坑全部暴露一遍。等这一圈验证通过后面接再多的业务任务也不会再出数据库层面的幺蛾子。