DataX
DataX copied to clipboard
hdfswriter在win下使用idea调试出现的bug
json文件如下
{ "setting": {}, "job": { "setting": { "speed": { "channel": 2 } }, "content": [ { "reader": { "name": "mysqlreader", "parameter": { "username": "root", "password": "123456", "column": [ "vid", "plane_no", "ao_no", "ao_name", "work_station", "stand_station", "type", "qty", "stuff_code", "re_stuff_code", "tooling_number", "tooling_qty", "total_tooling_qty" ], "splitPk": "vid", "connection": [ { "table": [ "tr_aoaao_resource" ], "jdbcUrl": [ "jdbc:mysql://172.16.26.252:3306/test?useUnicode=true&characterEncoding=utf8" ] } ] } }, "writer": { "name": "hdfswriter", "parameter": { "defaultFS": "hdfs://172.16.26.51:9820", "fileType": "orc", "path": "/user/hive/warehouse/zishi_test.db/adm_tr_aoaao_resource_copy3", "fileName": "adm_tr_aoaao_resource", "column": [ { "name": "vid", "type": "BIGINT" }, { "name": "plane_no", "type": "string" }, { "name": "work_station", "type": "string" }, { "name": "stand_station", "type": "string" }, { "name": "ao_no", "type": "string" }, { "name": "ao_name", "type": "string" }, { "name": "type", "type": "string" }, { "name": "part_no", "type": "string" }, { "name": "part_name", "type": "string" }, { "name": "qty", "type": "string" }, { "name": "stuff_code", "type": "string" }, { "name": "re_stuff_code", "type": "string" }, { "name": "tooling_number", "type": "string" }, { "name": "tooling_qty", "type": "string" }, { "name": "total_tooling_qty", "type": "string" } ], "writeMode": "append", "fieldDelimiter": "\u0001", "compress":"NONE" } } } ] } }
最后输入的几行日志如下: 2021-04-06 15:05:39.266 INFO 5968 --- [ task-1] c.s.dataxofflinetask.task.OfflineTask : 2021-04-06 15:05:39.265 [job-0] INFO HdfsWriter$Job - start delete tmp dir [hdfs://172.16.23.51:9820/user/hive/warehouse/sfdb_dev.db] . 2021-04-06 15:05:39.421 INFO 5968 --- [ task-1] c.s.dataxofflinetask.task.OfflineTask : 2021-04-06 15:05:39.421 [job-0] INFO HdfsWriter$Job - finish delete tmp dir [hdfs://172.16.23.51:9820/user/hive/warehouse/sfdb_dev.db] .
使用idea调试,把整个数据库删除了
我也有同样的问题,感觉是ide状态下获取父级路径出现了问题
我也有同样的问题,感觉是ide状态下获取父级路径出现了问题
原因:
- HdfsWriter类下面的buildTmpFilePath()方法拼接临时目录时方法读取当前运行环境的路径分隔符并拼接到临时路径中(例:
[hdfs://10.80.7.18:8020/home/hdfs/input/temp__e250c7ab_8228_4932_bf34_ac3ecd5617a6\student_hive__082ea874_a42b_4e87_9028_82d6b59ea801)
,你会发现student_hive(配置文件中的fileName)前面的分隔符是Windows系统下的’\‘而不是unix系统下的’/‘; - 在作业处理完后HdfsWriter类的post方法会调用执行HdfsHelper类的renameFile()方法,该方法完成重命名和删除临时文件的步骤。renameFile()方法读取srcFilePath(即第一步生成的临时文件路径)的父级路径用于删除操作的临时路径,这时由于路径分隔符不同,此时导致提取的父路径直接到达配置文件中属性path中的父路径级别,所以delete操作会把整个同步数据包括原来的数据库文件都删除了
if(tmpFilesParent == null){ tmpFilesParent = srcFilePah.getParent(); }
- 拼接路径分隔符应该以写入端的系统路径分隔符为准,而不是服务运行所在的系统为准。
我也有同样的问题,感觉是ide状态下获取父级路径出现了问题
原因:
- HdfsWriter类下面的buildTmpFilePath()方法拼接临时目录时方法读取当前运行环境的路径分隔符并拼接到临时路径中(例:
[hdfs://10.80.7.18:8020/home/hdfs/input/temp__e250c7ab_8228_4932_bf34_ac3ecd5617a6\student_hive__082ea874_a42b_4e87_9028_82d6b59ea801)
,你会发现student_hive(配置文件中的fileName)前面的分隔符是Windows系统下的’\‘而不是unix系统下的’/‘;- 在作业处理完后HdfsWriter类的post方法会调用执行HdfsHelper类的renameFile()方法,该方法完成重命名和删除临时文件的步骤。renameFile()方法读取srcFilePath(即第一步生成的临时文件路径)的父级路径用于删除操作的临时路径,这时由于路径分隔符不同,此时导致提取的父路径直接到达配置文件中属性path中的父路径级别,所以delete操作会把整个同步数据包括原来的数据库文件都删除了
if(tmpFilesParent == null){ tmpFilesParent = srcFilePah.getParent(); }
- 拼接路径分隔符应该以写入端的系统路径分隔符为准,而不是服务运行所在的系统为准。
感谢老哥
我也有同样的问题,感觉是ide状态下获取父级路径出现了问题
原因:
- HdfsWriter类下面的buildTmpFilePath()方法拼接临时目录时方法读取当前运行环境的路径分隔符并拼接到临时路径中(例:
[hdfs://10.80.7.18:8020/home/hdfs/input/temp__e250c7ab_8228_4932_bf34_ac3ecd5617a6\student_hive__082ea874_a42b_4e87_9028_82d6b59ea801)
,你会发现student_hive(配置文件中的fileName)前面的分隔符是Windows系统下的’\‘而不是unix系统下的’/‘;- 在作业处理完后HdfsWriter类的post方法会调用执行HdfsHelper类的renameFile()方法,该方法完成重命名和删除临时文件的步骤。renameFile()方法读取srcFilePath(即第一步生成的临时文件路径)的父级路径用于删除操作的临时路径,这时由于路径分隔符不同,此时导致提取的父路径直接到达配置文件中属性path中的父路径级别,所以delete操作会把整个同步数据包括原来的数据库文件都删除了
if(tmpFilesParent == null){ tmpFilesParent = srcFilePah.getParent(); }
- 拼接路径分隔符应该以写入端的系统路径分隔符为准,而不是服务运行所在的系统为准。
感谢老哥
链接:https://pan.baidu.com/s/1Wt5M10GlamNyI8MaqYZ3nQ 提取码:137e,这是经过优化后适配windows的,可以直接使用
json文件如下
{ "setting": {}, "job": { "setting": { "speed": { "channel": 2 } }, "content": [ { "reader": { "name": "mysqlreader", "parameter": { "username": "root", "password": "123456", "column": [ "vid", "plane_no", "ao_no", "ao_name", "work_station", "stand_station", "type", "qty", "stuff_code", "re_stuff_code", "tooling_number", "tooling_qty", "total_tooling_qty" ], "splitPk": "vid", "connection": [ { "table": [ "tr_aoaao_resource" ], "jdbcUrl": [ "jdbc:mysql://172.16.26.252:3306/test?useUnicode=true&characterEncoding=utf8" ] } ] } }, "writer": { "name": "hdfswriter", "parameter": { "defaultFS": "hdfs://172.16.26.51:9820", "fileType": "orc", "path": "/user/hive/warehouse/zishi_test.db/adm_tr_aoaao_resource_copy3", "fileName": "adm_tr_aoaao_resource", "column": [ { "name": "vid", "type": "BIGINT" }, { "name": "plane_no", "type": "string" }, { "name": "work_station", "type": "string" }, { "name": "stand_station", "type": "string" }, { "name": "ao_no", "type": "string" }, { "name": "ao_name", "type": "string" }, { "name": "type", "type": "string" }, { "name": "part_no", "type": "string" }, { "name": "part_name", "type": "string" }, { "name": "qty", "type": "string" }, { "name": "stuff_code", "type": "string" }, { "name": "re_stuff_code", "type": "string" }, { "name": "tooling_number", "type": "string" }, { "name": "tooling_qty", "type": "string" }, { "name": "total_tooling_qty", "type": "string" } ], "writeMode": "append", "fieldDelimiter": "\u0001", "compress":"NONE" } } } ] } }
最后输入的几行日志如下: 2021-04-06 15:05:39.266 INFO 5968 --- [ task-1] c.s.dataxofflinetask.task.OfflineTask : 2021-04-06 15:05:39.265 [job-0] INFO HdfsWriter$Job - start delete tmp dir [hdfs://172.16.23.51:9820/user/hive/warehouse/sfdb_dev.db] . 2021-04-06 15:05:39.421 INFO 5968 --- [ task-1] c.s.dataxofflinetask.task.OfflineTask : 2021-04-06 15:05:39.421 [job-0] INFO HdfsWriter$Job - finish delete tmp dir [hdfs://172.16.23.51:9820/user/hive/warehouse/sfdb_dev.db] .
使用idea调试,把整个数据库删除了
修改 com.alibaba.datax.plugin.writer.hdfswriter.HdfsWriter 中 IOUtils.DIR_SEPARATOR 替换成 IOUtils.DIR_SEPARATOR_UNIX 在 com.alibaba.datax.plugin.writer.hdfswriter.HdfsHelper 中的 renameFile(HashSet tmpFiles, HashSet endFiles) 方法中 在 String dstFile = it2.next().toString(); 下 添加一行 dstFile = dstFile.replace("\\","/"); 打包编译 将本地安装的datax\plugin\writer\hdfswriter\hdfswriter-0.0.1-SNAPSHOT.jar 替换成你打包好的文件
up!!大坑啊,前段时间碰到了。 不维护的项目,用还是要谨慎,不然就是删库跑了 删除错父目录直接原因是:windows写入异常情况下catch要删除临时目录,获取错误的父目录导致的 解决(有效防止越目录删除,只允许删除操作的目录):
String message = String.format("写文件文件[%s]时发生IO异常,请检查您的网络是否正常!", fileName);
LOG.error(message);
// !一定要控制,以免逻辑错误导致删除其他父类的目录!!!!!!只对跟写入到表path(可能是分区目录)的才允许删除!
String basePath = config.getString(Key.PATH, null);
LOG.info("只允许删除作业最上层目录:[{}]", basePath);
if (basePath != null) {
Path path = new Path(fileName);
LOG.warn("警告!要删除的父目录:[{}],最短目录[{}]", path.getParent().toString(), basePath);
if (path.getParent().toString().contains(basePath)) {
deleteDir(path.getParent());
}
}
throw DataXException.asDataXException(HdfsWriterErrorCode.Write_FILE_IO_ERROR, e);
根本原因是:hdfs目录没有''而在非unix'/'情况下,写入异常才暴露出来,是分区表就是表目录,不是分区(分桶)?表就是删库!
private String buildTmpFilePath(String userPath) {...}
private String buildFilePath() {...}
解决:都统一为/
oracle mysql这些导入导出应该猜不到这种删库雷吧 瑟瑟发抖中