使用sqoop导数据导入mysql报错duplicate entry for ' ' key primary
分析:1.查看日志,根据日志报错提示,排查Hive中源表和目标表中数据entry后的主键,是否数据本身发生重复(主键重复)。
(经排查,源表和目标表中数据(主键)并未发生重复,故此次可能并非数据(主键)本身重复导致。猜测可能使用Sqoop插入,开启MR并行后,多线程,SQL执行顺序,插入的数据混乱)
查看官方手册,发现Sqoop Export在使用多线程并发处理时,多个线程之间结果无事务关系,多个线程插入,会造成部分数据先提交到数据库,可能会造成插入数据重复,如果目标表设置主键,则会发生主键冲突。(参见官方文档:Sqoop User Guide (v1.4.6)
检查Sqoop导出脚本发现并未配置主键及并行度。
INSERT IGNORE INTO Table_name(……) VALUES(1,1),(2,2),(3,3);
使用IGNORE,如果插入的记录中存在重复值会忽略重复值的该记录行,不影响其他行的插入。
REPLACE INTO Table_name() VALUES(1,1),(2,2),(3,3)
使用replace当插入的记录遇到主键或者唯一重复时先删除表中重复的记录行再插入
INSERT TO Table_name() VALUES(1,1),(1,2) ON DUPLICATE KEY UPDATE NAME1=NAME1+
ON DUPLICATE KEY UPDATE后面使用VALUES指的是插入记录的值,而不使用VALUES指的是表的自身值。其后执行的UPDATE更新的记录是WHERE重复的主键或唯一键的ID。
(1)使用--staging-table参数,配置中间表,Sqoop先使用MR多线程写入中间表(此阶段无原则性),随后将中间表数据插入目标表(此阶段有事务),使用条件:中间表与目标表表结构一致,且必须为空。
#中间表参数,用于解决Sqoop多线程无原子性问题
--staging-table test
(2)使用更新主键参数和更新模式参数
#更新主键
--update-key "id,name"\
#更新模式(updateonly:只更新;allowinsert:已存在则更新,不存在则插入)
--update-mode allowinsert \
脚本中添加更新主键及更新模式参数
测试结果美丽,完美解决,解决方案1方案2均可,按需适用。
参考:
Sqoop User Guide (v1.4.6)
Sqoop工具模块之sqoop-export 原 - 云+社区 - 腾讯云
sqoop导出数据时如何选择update-key_日进一步-CSDN博客
Mysql on duplicate key update用法及优缺点 - 奕锋博客 - 博客园