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