postgres 9.3.6在小桌子上非常慢的截断

时间:2015-04-14 00:44:41

标签: postgresql truncate

在Postgres 9.3.6中,针对其中包含< 10行的表的截断通常需要2-3分钟。

在延迟期间,truncate停留在waiting = f和state = idle in transaction中。

在线研究,这个问题的标准答案是锁定争用,但这似乎并非如此。除了CI测试之外,在卸载的CI主机上会发生这种情况。根据pg_stat_activity,truncate是唯一运行的语句,并且根据pg_locks没有未授予的锁,因此我不会看到截断被阻塞等待锁定。

此外,我已经检查了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

1 个答案:

答案 0 :(得分:2)

state         | idle in transaction
query         | TRUNCATE TABLE foo_schema.foo

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

听起来这是一个应用程序方面的问题,但如果没有关于运行TRUNCATE的内容的信息,则无法确定。