问题背景
最近在一次项目的开发中,由于在pom文件中没有指定mysql-connector-java的version,则自动依赖了最新版的8.0.18包,在执行“LOAD DATA”时出现“nested exception is java.sql.SQLSyntaxErrorException: The used command is not allowed with this MySQL version” 的错误。
问题分析
- SQL语句写的有问题
- 8.0.18的驱动包对MySQL server版本有要求
- 8.0.18的驱动包对“LOAD DATA” 执行有问题
问题定位
- 对于验证SQL是否有问题:直接将语句在mysql客户端执行,没有问题;
- 升级的驱动包是否对mysql server版本有要求:我使用的mysql版本是5.6的,由于5.7是一个大的升级,于是在本地快速安装了个5.7的,再次验证,还是报同样的错误;
- 使用5.1.27版本的驱动包,执行SQL语句成功,由此可以定位到是mysql驱动包的问题。
问题原因
- 通过一步一步的跟踪代码发现,8.0.18的包中,将发送给mysql的信息包装在定义类NativePacketPayload的byte[] byteBuffer中,在执行"LOAD DATA" 语句时,查看byteBuffer中的内容为:
03 4c 4f 41 44 20 44 41
54 41 20 4c 4f 43 41 4c
20 49 4e 46 49 4c 45 20
27 44 3a 5c 5c 74 65 73
74 5c 5c 6d 79 73 71 6c
5f 32 30 31 39 31 32 31
32 5f 31 36 31 36 30 31
5f 74 65 73 74 2e 74 78
74 27 20 49 4e 54 4f 20
54 41 42 4c 45 20 54 5f
56 45 52 43 4b 5f 47 52
41 59 55 53 45 52 20 63
68 61 72 61 63 74 65 72
20 73 65 74 20 75 74 66
38 20 28 53 4f 47 4f 55
41 50 50 5f 49 44 2c 44
45 56 49 43 45 5f 49 44
29 - 5.1.27版本中,将发送给mysql的信息包装在定义Buffer类的byte[] byteBuffer 中,在执行"LOAD DATA" 语句时,查看byteBuffer中的内容为:
1e 00 00 00 03 4c 4f 41
44 20 44 41 54 41 20 4c
4f 43 41 4c 20 49 4e 46
49 4c 45 20 27 44 3a 5c
5c 74 65 73 74 5c 5c 6d
79 73 71 6c 5f 32 30 31
39 31 32 31 32 5f 31 36
31 36 30 31 5f 74 65 73
74 2e 74 78 74 27 20 49
4e 54 4f 20 54 41 42 4c
45 20 54 5f 56 45 52 43
4b 5f 47 52 41 59 55 53
45 52 20 63 68 61 72 61
63 74 65 72 20 73 65 74
20 75 74 66 38 20 28 53
4f 47 4f 55 41 50 50 5f
49 44 2c 44 45 56 49 43
45 5f 49 44 29
-通过对比,很容易发现,5.1.27的包的信息中,前面多了四个字节,1e 00 00 00,而8.0.18的包中缺少这几个字节,导致发送mysql server执行命令是报错误。
总结
- 该问题可能是mysql驱动包的bug,我只测试的是8.0.18版本,后期版本是否已修复未测试
- 若在开发中遇到类似的问题,在SQL没问题的情况下,试试替换下低版本的包
- 在平常遇到比较棘手的问题时,要擅于通过跟踪源码,找到出现问题的根本原因