Hadoop DBWritable : Unable to insert record to mysql from Hadoop reducer

标签 hadoop mysql-error-1064 hadoop-streaming hadoop-plugins

插入表时遇到重复输入问题。

我一直使用Hadoop mapper从文件中读取记录。它成功地从文件中完全读取记录​​。但是当通过Hadoop reducer将记录写入mysql数据库时,出现以下错误。

java.io.IOException:键“PRIMARY”的重复条目“505975648”

但是 Mysql 表仍然是空的。无法从 Hadoop DBWritable reducer 将记录写入 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) 在 com.mysql.jdbc.SQLError.createSQLException (SQLError.java:926) 在 com.mysql.jdbc.ConnectionImpl.getMutex(ConnectionImpl.java:3018) 在 com.mysql.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:4564) 在 org.apache.hadoop.mapred.lib.db.DBOutputFormat$DBRecordWriter.close(DBOutputFormat.java:72) 在 org.apache.hadoop.mapred.ReduceTask$OldTrackingRecordWriter.close(ReduceTask.java:467) 在 org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:539) 在 org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:421) 在 org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:262)

2014 年 6 月 4 日下午 1:23:36 org.apache.hadoop.mapred.LocalJobRunner$作业运行 警告:job_local_0001 java.io.IOException:键“PRIMARY”的重复条目“505975648” 在 org.apache.hadoop.mapred.lib.db.DBOutputFormat$DBRecordWriter.close(DBOutputFormat.java:77) 在 org.apache.hadoop.mapred.ReduceTask$OldTrackingRecordWriter.close(ReduceTask.java:467) 在 org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:531) 在 org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:421) 在 org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:262)

最佳答案

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端的general log,看看有没有什么东西被执行了。很可能您会看到您的事务因错误而被回滚。要解决此问题,请确保主键是唯一的。如果更新/更新插入是您想要的,您可以制作一个输出/记录器来执行此操作,但这是另一回事。

关于Hadoop DBWritable : Unable to insert record to mysql from Hadoop reducer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24032006/

相关文章:

hadoop - FANMOD - 使用 Hadoop/MapReduce 进行子图搜索

hadoop - HDFS空间配额-如果父文件夹的配额少于其子文件夹的配额,该怎么办

php - 如何在单个 sql 查询中处理多对多关系?

php - 如果 mysql_query 不成功则显示错误

Windows 上的 Python Hadoop 流,脚本不是有效的 Win32 应用程序

shell - 在 oozie 工作流 (HUE) 中,如何将参数从 shell 操作传递到 HDFS fs 操作

hadoop - 从 Cloudera 中删除失效主机

mongodb - 使用 mongo-hadoop 连接器的 Hadoop 流式传输失败

mysql - 如何从 MySQL 中的 COUNT(*) 中减去整数

Python Streaming : how to reduce to multiple outputs?(尽管使用 Java 是可能的)