bra*_*obo 3 postgresql clustering locking
由于频繁的新记录和更新记录导致索引和存储碎片,我面临性能下降和存储使用量增加的问题。
VACUUM 没有多大帮助。
不幸的是,CLUSTER 不是一个选项,因为它会导致停机并且 pg_repack 不适用于 AWS RDS。
我正在寻找 CLUSTER 的 hacky 替代品。在我的本地测试中似乎可以正常工作的一个是:
begin;
create temp table tmp_target as select * from target;
delete from target;
insert into target select * from tmp_target order by field1 asc, field2 desc;
drop table tmp_target;
commit;
Run Code Online (Sandbox Code Playgroud)
ctid看起来的顺序是正确的:
select ctid, field1, field2 from target order by ctid;
Run Code Online (Sandbox Code Playgroud)
问题是:这看起来好吗?是否会锁定target表以SELECT查找导致应用程序停机的查询?有没有办法列出事务中涉及的锁?
如果它只是关于表格膨胀,VACUUM FULL那么它是用来做这件事的工具。(VACUUM只有在它可以在最后机会截断它的情况下才缩小物理文件。)但是,VACUUM FULL也会在表上使用排他锁,就像CLUSTER.
在没有排他锁的情况下做同样的事情pg_repack是你正在寻找的工具。不幸的是,亚马逊似乎不允许这样做。
手动解决方案引入了各种极端情况和竞争条件。在我们讨论最佳解决方案之前,您需要准确地指定您的表和可能的访问模式。
无论哪种方式,您当前的解决方案都不好。在删除所有行(锁定它们)之后进行排序操作,这不会缩短查询的停机时间(锁定的持续时间)SELECT。
如果您没有并发写入访问权限并且没有依赖对象,这可能会更好:
BEGIN;
CREATE TEMP TABLE tmp_target AS TABLE target ORDER BY field1, field2 DESC;
TRUNCATE target;
INSERT INTO target TABLE tmp_target;
-- DROP TABLE tmp_target; -- optional; dropped at end of session automatically
COMMIT;
Run Code Online (Sandbox Code Playgroud)
在获取锁之前在后台排序。
严格来说,INSERT没有ORDER BY以任何物理顺序自由写入行。但实际上,它会用普通SELECT * FROM(或TABLE简称)复制临时表的当前物理顺序。
使用TRUNCATE而不是DELETE,这对于大表来说更快。请注意某些含义,例如TRUNCATE不适用于 FK 约束。阅读手册以了解完整内容。
您可能希望在之前删除现有索引TRUNCATE并在之后重新创建INSERT以使其更快。
有关的:
| 归档时间: |
|
| 查看次数: |
1063 次 |
| 最近记录: |