通过 JDBC 从 Spark 提取表数据时出现 PostgreSQL 错误

Posted

技术标签:

【中文标题】通过 JDBC 从 Spark 提取表数据时出现 PostgreSQL 错误【英文标题】:PostgreSQL error when extracting table data via JDBC from Spark 【发布时间】:2015-09-24 23:09:21 【问题描述】:

我让 Spark 到 HAWQ JDBC 连接正常工作,但现在两天后从表中提取数据出现问题。 Spark 配置没有任何变化...

简单的步骤 #1 - 从 HAWQ 中的简单表中打印模式 我可以创建一个 SQLContext DataFrame 并连接到 HAWQ db:

df = sqlContext.read.format('jdbc').options(url=db_url, dbtable=db_table).load()
df.printSchema()

哪些打印:

root
 |-- product_no: integer (nullable = true)
 |-- name: string (nullable = true)
 |-- price: decimal (nullable = true)

但是当实际尝试提取数据时:

df.select("product_no").show()

这些错误弹出...

org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 0.0 failed 1 times, most recent failure: Lost task 0.0 in stage 0.0 (TID 0, localhost): 
org.postgresql.util.PSQLException: ERROR: could not write 3124 bytes to temporary file: No space left on device (buffile.c:408)  (seg33 adnpivhdwapda04.gphd.local:40003 pid=544124) (cdbdisp.c:1571)
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2182)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1911)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:615)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:465)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:350)
    at org.apache.spark.sql.jdbc.JDBCRDD$$anon$1.<init>(JDBCRDD.scala:372)
    at org.apache.spark.sql.jdbc.JDBCRDD.compute(JDBCRDD.scala:350)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:244)
    at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:35)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:244)
    at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:35)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:244)
    at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:35)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:244)
    at org.apache.spark.api.python.PythonRDD$WriterThread$$anonfun$run$3.apply(PythonRDD.scala:248)
    at org.apache.spark.util.Utils$.logUncaughtExceptions(Utils.scala:1772)
    at org.apache.spark.api.python.PythonRDD$WriterThread.run(PythonRDD.scala:208)

我尝试过的事情(但如果有更精确的步骤愿意再试一次):

在 HAWQ 主节点上尝试了“df -i”,但利用率只有 1% 在 HAWQ 数据库上尝试了 dbvacuum(不推荐使用 VACUUM ALL 在 HAWQ 上) 尝试创建这个很小的新数据库(使用单个表,3 列),没有运气

这不可能是真正的内存不足,那么是在哪里以及是什么导致了这个问题??

【问题讨论】:

可能是权限问题。请检查 postgres 日志;你在浑水中游泳。带太阳镜。 /ORM 请显示df -hmount 以及来自psqlSHOW temp_tablespaces 的完整、未修改的输出。另外 +1 并感谢您显示完整的堆栈跟踪。 【参考方案1】:

无法将 3124 字节写入临时文件:设备上没有剩余空间

用于临时文件的卷已满。然后临时文件将在出错时被删除,因此您实际上看不到 df 中的完整卷。

在大多数 Linux 系统上,这可能是一个 tempfs,例如 /tmp。如果是这样,它由虚拟内存支持。要确认,请检查mount 并检查PostgreSQL 的temp_tablespaces (SHOW temp_tablespaces) 的设置。如果为空,PostgreSQL 将使用默认表空间,这不太可能是 tempfs,但如果设置了,请检查该表空间的位置。如果它是在 tempfs 上,您可能需要移动它。

它也可能以某种方式填充主表空间,但如果它目前只有 1% 的利用率,这是极不可能的。也许大规模失控的递归 CTE 可以做到,但不太可能。

配额管理也是一种可能。也许配置了文件系统配额?

【讨论】:

你是对的@Craig Ringer,谢谢!我没有看到 /tmp 被填满。果然,它的利用率是 100%。不知道那里写了什么,但是 HAWQ 不能更新表,所以它只会创建新表(......还有更多新表,谁知道是否有任何引用?)。最后一点:一般管理员帐户没有显示 100% 的利用率,只有在以 root 身份运行 df 后问题才显现出来。

以上是关于通过 JDBC 从 Spark 提取表数据时出现 PostgreSQL 错误的主要内容,如果未能解决你的问题,请参考以下文章

通过 Spark 运行时出现 Sqoop 错误

由于 PySpark 时间戳,将 Spark 数据帧保存到 Azure Synapse 时出现问题

尝试使用 apache spark 加载模块时出现 Databricks 错误 [重复]

在一个查询中两次从同一个表中提取时出现问题

在运行 spark 应用程序时包含 aws jdbc 驱动程序

使用 JDBC 写入编写 AWS Glue DynamicFrame 时出现 PostreSQL 枚举问题