postgres 截断很慢

Posted

技术标签:

【中文标题】postgres 截断很慢【英文标题】:postgres truncate is slow 【发布时间】:2013-11-25 00:24:08 【问题描述】:

在 postgres 9.2 (CentOS) 中,TRUNCATE TABLE 命令有时需要很长时间才能运行。有一次,截断一个有 100K 记录的表需要 1.5 多个小时,在其他情况下甚至更长。当我使用 pgAdmin 截断表时,也发生了这个问题。可能的原因是什么?以及如何提高截断性能?

服务器上有 16GB 内存,shared_buffers = 1536MB

【问题讨论】:

这可能意味着 TRUNCATE 进程正在等待获取锁;和其他一些进程需要很长时间才能释放它们的锁。但是这个问题在这里并不是真正的主题。 【参考方案1】:

TRUNCATE 必须为被截断的表刷新shared_buffers,并且它必须取消链接旧文件,这在像ext3 这样的删除速度很慢的文件系统上可能会很慢。

1.5 小时是相当极端的,因为我们通常最多只能说几秒钟。您很可能有其他会话持有表上的锁,从而阻止TRUNCATE 继续进行。请参阅pg_catalog.pg_lockspg_catalog.pg_stat_activity

The PostgreSQL wiki article on lock monitoring 应该很有用。

另见:Postgresql Truncation speed

【讨论】:

【参考方案2】:

尝试断开与数据库的所有其他连接。 我花了很长时间才截断 58000 条记录。

在我断开我的 postgres 数据库与 PyCharm DB Navigator 的连接后,开发服务器等总共花费了 118 毫秒。

【讨论】:

【参考方案3】:

检查truncate 是否被任何查询阻止

SELECT
    activity.pid,
    activity.usename,
    activity.query,
    blocking.pid AS blocking_id,
    blocking.query AS blocking_query
FROM pg_stat_activity AS activity
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(activity.pid));

如有必要,终止它 SELECT pg_terminate_backend(PID);

【讨论】:

【参考方案4】:

这只是发生在我和我的团队身上。我们正在使用 Postgres 12,并且正在使用 Apache NiFi 进行一些处理。卡住了。

我们做了一个:

systemctl status postgresql-12

然后我注意到很多“TRUNCATED Waiting”,我继续尝试重新加载 Postgres,但没有成功,然后就杀死了每个卡住的进程。

在那之后它起作用了,我们能够重新启动作业并且只用了不到一秒钟的时间。

【讨论】:

以上是关于postgres 截断很慢的主要内容,如果未能解决你的问题,请参考以下文章

在 Postgres 中将时间戳截断为 5 分钟的最快方法是啥?

AWS Glue - 在插入之前截断目标 postgres 表

Postgres 截断重新启动身份不会重新启动身份

有没有办法在 postgres 测试容器中删除所有表或截断

使用 OR 语句时 Postgres SQL 很慢

sql 存储过程,删除Postgres中所有表中的所有条目而不删除或截断,并使用可选的忽略。