我对postgresql没有那么有经验。
做了一个简单的命令
DELETE FROM table_name where some_condition;
涉及数千行。但是实际上在该命令之后,磁盘空间变得更小了。
任何想法出了什么问题?我启用了 autovacuum = on 并尝试执行 'VACUUM FULL;' 但这消耗了我的整个磁盘空间。
我想做的很简单。删除行并获取空间。涉及的空间很大,机器上没有那么多空间。有没有办法做到这一点?
我对postgresql没有那么有经验。
做了一个简单的命令
DELETE FROM table_name where some_condition;
涉及数千行。但是实际上在该命令之后,磁盘空间变得更小了。
任何想法出了什么问题?我启用了 autovacuum = on 并尝试执行 'VACUUM FULL;' 但这消耗了我的整个磁盘空间。
我想做的很简单。删除行并获取空间。涉及的空间很大,机器上没有那么多空间。有没有办法做到这一点?
autovacuum
除非您确切知道自己在做什么,否则应该在任何现代 Postgres 数据库中运行。但 autovacuum不会缩小表格,除非是极少数情况。它会安排定期VACUUM
和ANALYZE
作业,但从不 VACUUM FULL
安排,这会在已处理的表和索引上获得排他锁。VACUUM
但是,通过清理死元组(以及其他各种善举)有助于避免表和索引膨胀,从而为将来对同一对象的写操作提供空间——但尚未将空间返回给操作系统。
你写:
试图执行 'VACUUM FULL;' 但这消耗了我的整个磁盘空间。
你的意思是暂时的?因为这就是这样VACUUM FULL
做的。但是当它完成时,表和相关的索引会被减少到它们的最小大小——这通常是不可取的,除非你迫切需要磁盘空间或者行永远不会更新。
VACUUM FULL
适合您的工具也是如此,除非您的磁盘空间已经用完 - 最好不要一开始就发生这种情况。所以你需要创造一些回旋的空间让它发挥它的魔力。
还有社区工具pg_repack
,它可以做与VACUUM FULL
没有排他锁相同的事情。但它也需要一些可用的磁盘空间才能工作。更多详细信息的相关答案:
要删除表的所有行并立即释放磁盘空间,请使用TRUNCATE
. 它有效地在磁盘上写入一个新文件并删除旧文件。这也是为什么它通常不能与数据库上的并发负载一起使用的原因。
TRUNCATE table_name;
VACUUM FULL
通过创建每个表的新版本并复制所有数据来工作。在新表完成之前不会删除旧表,因此VACUUM FULL
操作会在处理时临时增加磁盘空间。请参阅PostgreSQL 文档中的此注释(重点是我的):
提示:由于大量更新或删除活动导致表包含大量死行版本时,普通 VACUUM 可能无法令人满意。如果您有这样的表并且需要回收它占用的多余磁盘空间,则需要使用 VACUUM FULL,或者 CLUSTER 或 ALTER TABLE 的表重写变体之一。这些命令重写表的全新副本并为其构建新索引。所有这些选项都需要排他锁。请注意,它们还临时使用大约等于表大小的额外磁盘空间,因为表和索引的旧副本在新副本完成之前无法释放。
VACUUM
另一方面,常规只是从数据库文件中修剪已删除的行和索引条目。
如果您先运行常规VACUUM
然后尝试运行VACUUM FULL
. 如果您尝试VACUUM FULL
在特定表上运行,您也可能会取得更大的成功。如果您以正确的顺序运行它们,您可能能够恢复足够的磁盘空间,以便数据库中的其余表可以运行VACUUM FULL
。否则,您将需要找到一些增加可用磁盘空间的方法,以便VACUUM FULL
完成。