我是postgres的新手,
我在实时服务器上有一个 2000 万行的表 - 我需要删除大部分行,但不是全部。我想这样做而不影响访问该表的其他读/写进程(非常频繁)。
我有一种方法可以一次删除大约 100-400K 行块。在每次删除之间,我想让查询休眠 - 以便其他操作有机会访问该表。
我有代码,但我相信这个版本,它会在查询运行的整个过程中锁定表(所有的睡眠)。我怎样才能在进程休眠时真正释放表?谢谢!!
到目前为止我的代码:
CREATE SEQUENCE tmp_sq increment by 1 minvalue 1 maxvalue 53 start with 1;
DO $$
DECLARE
w_counter integer;
BEGIN
w_counter := (SELECT nextval('tmp_sq'));
while w_counter < 53 loop
raise notice 'Value: %', w_counter ;
w_counter := (SELECT nextval('tmp_sq'));
-- this way of breaking up the delete into chunks works for my table because of dates.
delete from table_a where date_part('week',my_date) = w_counter;
raise notice ' Rows Were Deleted ';
--sleep
raise notice 'Sleeping Now.....';
perform pg_sleep(60);
end loop;
END $$;
表本身只锁定在 ROW EXCLUSIVE 模式下,这不应该阻止对表的任何正常操作,只会阻止诸如 DROP、ALTER 和 CREATE INDEX 之类的操作。
正在删除的每一行都将在持续时间内被锁定。如果其他进程试图更新行(或自己删除它们),这应该只阻止其他进程。通常,通过批量删除,您会删除其他人不关心的行,这意味着没有其他人会尝试更新它们。
如果您确实需要定期解锁所有已删除的行和表,那么您需要在单独的事务中执行删除的每个循环。在 DO 块中没有简单的方法来执行此操作,因为整个块在单个事务中运行。所以你应该把你的循环放在 PostgreSQL 之外,比如 bash、perl、python 等。