在 Postgres 9.3.6 中,对包含 <10 行的表进行截断通常需要 2-3 分钟。
在延迟期间,截断在事务中陷入 waiting=f 且 state=idle 状态。
在网上研究这个问题,这个问题的标准答案是锁争用,但这里的情况似乎并非如此。这种情况发生在除 CI 测试之外已卸载的 CI 主机上。根据 pg_stat_activity,truncate 是唯一正在运行的语句,并且根据 pg_locks,没有未授予的锁,因此在我看来,truncate 并没有被阻塞等待锁。
此外,我检查了 postgres 日志中是否有死锁错误,但没有发现任何错误。
(请注意,我们使用截断而不是 10 行,因为这个问题是在 CI 测试期间发生的 - 在正常生产操作期间,此表中有 10^6 行,因此截断是有意义的。这是一个工作中间表,之前被截断每次运行 ETL 流程。)
我不知道从这里去哪里——任何建议将不胜感激!以下是相关查询的输出:
warehouse=# select pid,usename,backend_start,xact_start,query_start,now()-query_start as wait_time,state_change,waiting,state,query from pg_stat_activity;
-[ RECORD 1 ]-+-----------------------------------------------------------------------------------------------------------------------------------------------
pid | 25123
usename | dev
backend_start | 2015-04-13 23:25:47.728267+00
xact_start | 2015-04-14 00:23:39.969074+00
query_start | 2015-04-14 00:23:39.969074+00
wait_time | 00:00:00
state_change | 2015-04-14 00:23:39.969081+00
waiting | f
state | active
query …Run Code Online (Sandbox Code Playgroud) 我有一个名为 Recording 的案例类,我可以使用 Spray-json 正确序列化它,但无法序列化 List[Recording]。
我看到的关于列表序列化的答案涉及缺少 DefaultJsonProtocol._ 的导入,但这对我没有帮助。
这是代码:
import spray.json._
import scala.collection.immutable
object RecordingJsonProtocol extends DefaultJsonProtocol {
implicit val recordingFormat = jsonFormat2(Recording.apply)
}
case class Recording(name: String, hashOffsetIndex: immutable.Map[String, Int])
object RecordingLoader {
import RecordingJsonProtocol._
import DefaultJsonProtocol._
def recordingsToJson(filename: String, recordings : List[Recording]) = {
println(recordings.toJson.prettyPrint)
}
}
Run Code Online (Sandbox Code Playgroud)
我收到的错误是:
Error:(16, 24) Cannot find JsonWriter or JsonFormat type class for List[Recording]
println(recordings.toJson.prettyPrint)
^
Run Code Online (Sandbox Code Playgroud)
编辑:问题已解决
import DefaultJsonProtocol._
Run Code Online (Sandbox Code Playgroud)
是多余的,因为 RecordingJsonProtocol 扩展了 DefaultJsonProtocol ——但这不仅仅是多余的,它还会阻止 RecordingJsonProtocol 工作。
我们将Postgres 9.3中的数据导出到文本文件中以供Spark使用.
我们希望使用ASCII 31字段分隔符作为分隔符而不是\ t,以便我们不必担心转义问题.
我们可以在这样的shell脚本中这样做:
#!/bin/bash
DELIMITER=$'\x1F'
echo "copy ( select * from table limit 1) to STDOUT WITH DELIMITER '${DELIMITER}'" | (psql ...) > /tmp/ascii31
Run Code Online (Sandbox Code Playgroud)
但是我们想知道,是否有可能在"纯"postgres中指定一个不可打印的字形作为分隔符?
编辑:我们试图按照http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html使用postgres转义约定
warehouse=> copy ( select * from table limit 1) to STDOUT WITH DELIMITER '\x1f';
Run Code Online (Sandbox Code Playgroud)
并收到
ERROR: COPY delimiter must be a single one-byte character
Run Code Online (Sandbox Code Playgroud)