【问题标题】:postgres 9.3.6 very slow truncates on small tablepostgres 9.3.6 在小桌子上的截断速度非常慢
【发布时间】:2015-04-14 00:44:41
【问题描述】:

在 Postgres 9.3.6 中,对包含

在延迟期间,截断卡在事务中的 waiting=f 和 state=idle 中。

在线研究这个问题,这个问题的标准答案是锁争用,但这里似乎并非如此。这发生在除 CI 测试外已卸载的 CI 主机上。根据 pg_stat_activity,truncate 是唯一运行的语句,并且根据 pg_locks 没有未授予的锁,所以在我看来,truncate 并没有被阻塞等待锁。

此外,我检查了 postgres 日志中是否存在死锁错误,但没有发现。

(请注意,我们使用的是截断与 10 行,因为这个问题发生在 CI 测试期间——在正常生产操作期间,此表中有 10^6ish 行,所以截断是有意义的。这是一个工作中间表,在每次运行 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         | 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 2 ]-+-----------------------------------------------------------------------------------------------------------------------------------------------
pid           | 5288
usename       | fk-etl
backend_start | 2015-04-14 00:21:20.913133+00
xact_start    | 2015-04-14 00:21:20.921312+00
query_start   | 2015-04-14 00:21:20.92142+00
wait_time     | 00:02:19.047654
state_change  | 2015-04-14 00:21:20.928318+00
waiting       | f
state         | idle in transaction
query         | TRUNCATE TABLE foo_schema.foo


warehouse=# select * from pg_locks;
warehouse=# SELECT relation::regclass as object, mode,granted,pid FROM pg_locks;
-[ RECORD 1 ]---------------------------------------------------------------------------
object  | 
mode    | ExclusiveLock
granted | t
pid     | 5288
-[ RECORD 2 ]---------------------------------------------------------------------------
object  | pg_locks
mode    | AccessShareLock
granted | t
pid     | 25123
-[ RECORD 3 ]---------------------------------------------------------------------------
object  | 
mode    | ExclusiveLock
granted | t
pid     | 25123
-[ RECORD 4 ]---------------------------------------------------------------------------
object  | foo_schema.foo_compound_idx
mode    | AccessExclusiveLock
granted | t
pid     | 5288
-[ RECORD 5 ]---------------------------------------------------------------------------
object  | foo_schema.foo
mode    | ShareLock
granted | t
pid     | 5288
-[ RECORD 6 ]---------------------------------------------------------------------------
object  | foo_schema.foo
mode    | AccessExclusiveLock
granted | t
pid     | 5288
-[ RECORD 7 ]---------------------------------------------------------------------------
object  | foo_schema.foo_pkey
mode    | AccessExclusiveLock
granted | t
pid     | 5288
-[ RECORD 8 ]---------------------------------------------------------------------------
object  | pg_toast.pg_toast_10043463
mode    | ShareLock
granted | t
pid     | 5288
-[ RECORD 9 ]---------------------------------------------------------------------------
object  | pg_toast.pg_toast_10043463
mode    | AccessExclusiveLock
granted | t
pid     | 5288
-[ RECORD 10 ]--------------------------------------------------------------------------
object  | pg_toast.pg_toast_10043463_index
mode    | AccessExclusiveLock
granted | t
pid     | 5288
-[ RECORD 11 ]--------------------------------------------------------------------------
object  | 
mode    | ExclusiveLock
granted | t
pid     | 5288

【问题讨论】:

    标签: postgresql truncate


    【解决方案1】:
    state         | idle in transaction
    query         | TRUNCATE TABLE foo_schema.foo
    

    TRUNCATE 已完成,会话正在等待下一条语句或 COMMIT

    这听起来像是一个应用程序端的问题,但如果没有关于运行 TRUNCATE 的信息,就无法肯定地说。

    【讨论】:

    • 这是一个非常有用的见解!该应用程序是一个 Pentaho Kettle 转换,并且截断由一个表输出步骤运行,该步骤也插入记录。我可以看到发布提交可能会很慢。我们将在那里重新聚焦。谢谢!
    • ...事实证明,我们在上游有一个生成 UUID 步骤,它在 /dev/random 上阻塞。当表输出步骤初始化时,它运行截断,但直到 /dev/random 吐出足够的随机性以生成 UUID 并实际发送一行时才提交截断。
    猜你喜欢
    • 2013-11-25
    • 2016-05-21
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 2015-01-16
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多