DataX支持SQL Server到MySQL同步,但需绕开TLS握手失败、字段类型不兼容、JSON变量传参漏引号等坑;必须用sqlserverreader+mysqlwriter插件组合,connection中jdbcUrl须为数组且显式指定DatabaseName,datetime/bit字段需对应DATETIME/TINYINT(1),禁用"*"而应明确列名,TLSv1问题需修改java.security启用,表名动态传参用-p并注意转义,条件过滤应使用querySql而非拼接WHERE,channel数须与JVM内存匹配调优。

能用,但必须绕开几个硬坑:TLS握手失败、字段类型不兼容、JSON配置里变量传参容易漏引号。DataX本身不提供图形界面,所有同步逻辑都靠job.json和命令行参数驱动,适合批量离线场景,不适合实时或小量单表调试。
SQL Server到MySQL的JSON配置关键点
核心是sqlserverreader和mysqlwriter两个插件配合,不能直接复用MySQL到MySQL的模板。常见错误是把table写成字符串而非数组,或者jdbcUrl里缺数据库名参数。
-
connection下的jdbcUrl必须是数组,哪怕只配一个,例如["jdbc:sqlserver://192.168.2.84:1433;DatabaseName=mydb"] - SQL Server连接字符串要显式加
DatabaseName=xxx,否则sqlserverreader会报“Cannot resolve database name” - 如果源表含
datetime或bit字段,MySQL目标表对应列必须建为DATETIME或TINYINT(1),否则mysqlwriter写入时直接报DataXException -
column建议明确列出字段名,避免用["*"]——SQL Server的uniqueidentifier或xml类型会被转成字符串,MySQL端没对应类型就崩
执行时遇到TLS10被拒怎么办
错误信息"The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]"本质是JDK 1.8u251+默认禁用了TLSv1/TLSv1.1,而老SQL Server(如2008/2012)只支持TLSv1。
- 找到
java.security文件,路径通常是$JAVA_HOME/jre/lib/security/java.security - 编辑该文件,注释或删掉
jdk.tls.disabledAlgorithms行末尾的TLSv1, TLSv1.1(保留SSLv3等其他项) - 重启DataX进程,不需重装JDK
- 更安全的做法是升级SQL Server到2016+并启用TLSv1.2,但生产环境往往做不到
如何动态传入表名并避免SQL注入风险
用-p参数传变量最常用,但python datax.py xxx.json -p "-DreadTable=tb_user -DwriteTable=user"这种写法在Linux shell里容易因空格或特殊字符出错。
- 变量名必须和JSON里
${readTable}完全一致,大小写敏感 - 如果表名含短横线(如
log-2024),必须用双引号包住整个-p参数:-p "-DreadTable=\"log-2024\"" -
preSql里用truncate table ${writeTable}是可行的,但严禁拼接WHERE条件——DataX不校验SQL语法,拼错直接导致全表清空 - 真正需要条件过滤时,改用
querySql字段,例如"querySql": ["SELECT * FROM tb_user WHERE create_time > '2024-01-01'"],此时table字段必须删掉
最易忽略的是channel并发数和JVM内存的匹配关系:设"channel": "5"但只给--jvm="-Xms2G -Xmx2G",任务大概率OOM;反过来设"channel": "1"却堆内存开8G,纯属浪费。实际调优得看单表数据量——百万级用3~5个channel,千万级建议拆成多个job分批跑。


















