插入表时面临重复输入问题。
我使用Hadoop从file.It读取记录,通过Hadoop还原器将记录写入mysql数据库时,成功地从file.But完全读取记录,出现错误。
java.io.IOException:关键字“主”的重复条目“505975648”
但是Mysql表仍然是empty.Unable,可以从Hadoop DBWritable还原器将记录写入mysql表。
以下是错误日志:
警告:已经调用了com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close()。此状态下的操作无效。( sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native方法)在sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57),sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45),java.lang.reflect.Constructor.newInstance(Constructor.java:526),com.mysql.jdbc.Util.handleNewInstance(Util.java:406),com.mysql.jdbc.Util.getInstance(Util.java:381),com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926) at com.mysql.jdbc.ConnectionImpl.getMutex(ConnectionImpl.java:3018) at com.mysql.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:4564) at org.apache.hadoop.mapred.lib.db.DBOutputFormat$DBRecordWriter.close(DBOutputFormat.java:72) at org.apache.hadoop.mapred.ReduceTask$OldTrackingRecordWriter.close(ReduceTask.org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:539) at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:421) at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:262)
Jun 04,2014年下午1:23:36运行警告: org.apache.hadoop.mapred.lib.db.DBOutputFormat$DBRecordWriter.close(DBOutputFormat.java:77) org.apache.hadoop.mapred.ReduceTask$OldTrackingRecordWriter.close(ReduceTask.java:467) at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:531) at org.apache.hadoop.mapred job_local_0001 java.io.IOException:重复输入“505975648”键以表示“主”org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:262) .ReduceTask.run(ReduceTask.java:421)
发布于 2014-10-30 22:02:01
DBOutputFormat / DBRecordWriter在数据库事务中执行所有操作。虽然您现在可能没有表中的任何内容,但是如果您尝试使用相同的主键在同一个事务中执行两个插入,您将得到这个错误,这就是正在发生的情况。要更好地跟踪这一点,可以添加日志记录。您可以通过为DBOutputFormat获取代码并创建一个新的类似名称的类来做到这一点。我给我的LoggingDBOutputFormat打了电话。更新职务代码以替代使用这种新的输出格式。对于新的输出格式,您可以更改close方法,以便在语句执行之前记录它们:
/** {@inheritDoc} */
public void close(TaskAttemptContext context) throws IOException {
try {
LOG.warn("Executing statement:" + statement);
statement.executeBatch();
connection.commit();
} catch (SQLException e) {
try {
connection.rollback();
}
catch (SQLException ex) {
LOG.warn(StringUtils.stringifyException(ex));
}
throw new IOException(e.getMessage());
} finally {
try {
statement.close();
connection.close();
}
catch (SQLException ex) {
throw new IOException(ex.getMessage());
}
}
}然后,您可以检查mysql侧的常规日志,以查看是否执行了任何操作。您可能会看到您的事务是根据错误回滚的。若要解决此问题,请确保主键是唯一的。如果更新/更新是您想要的,那么您可以创建一个输出/记录编写器来完成这一任务,但这是另一项任务。
https://stackoverflow.com/questions/24032006
复制相似问题