Postgres列太大而无法清除

时间:2019-06-24 11:27:40

标签: ruby-on-rails postgresql heroku heroku-postgres

不到2小时前,我发现代码中有一个大问题。由于意外的for循环,我在数据库的List.keywords列中填充了一段巨大的文本。一切都被封锁。

当我意识到错误时,我将代码更改为在每次保存记录时清空该列。一切都阻塞了。

我尝试通过使用Rails迁移remove_column :lists, :keywords来迁移数据库。迁移也失败了。

尽管最后一次迁移必须完成了某些任务,但现在代码又很快了。除了Lists(其中keywords列给我的问题)。保存List时,大约需要5秒钟。阅读速度很快。

如果我执行heroku pg:psql并检出lists表,则keywords列仍然存在,所以我猜这就是所有数据仍然存在的地方,以及为什么表这么慢。 / p>

你们将如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

问题在于,调用List记录将尝试将该记录加载到内存中。专栏是如此之大,以至于即使在Rails中也会失败。

与Postgres工程师交谈后的解决方案:

我使用heroku pg:psql -a <myapp>登录到heroku上的postgres生产控制台。我检查了清单2203的值是什么

SELECT "keywords"
FROM "lists"
WHERE id = 2203;

我看到其中有很多文字,对此感到非常高兴,因为这是我第一次真正看到问题。首先,我想清除列表

-- Doing this in a transaction, so if I don't like what happened, I can call ROLLBACK; to start over
BEGIN;
UPDATE "lists"
WHERE id = 2203
SET keywords = '';

SELECT "keywords"
FROM "lists"
WHERE id = 2203;

-- I was happy with the result as it was empty, so I committed the transaction
COMMIT;
-- If you're not happy, do ROLLBACK; to start over

好的,这是一个List完成的时间,是时候全部完成了

-- not setting the WHERE as I want to do this on all of them.
BEGIN;
UPDATE "lists"
SET keywords = '';

-- here you can SELECT to do some checks at some records, see if they are empty.

COMMIT;

Voila,我的Rails应用再次开始快速运行,不再阻塞。

希望这可以在将来对某人有所帮助。可能是我。