Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 如何在不锁定表的情况下在Postgres中回填列?_Postgresql_Bulkupdate - Fatal编程技术网

Postgresql 如何在不锁定表的情况下在Postgres中回填列?

Postgresql 如何在不锁定表的情况下在Postgres中回填列?,postgresql,bulkupdate,Postgresql,Bulkupdate,最近,我在我的4000多万行Postgres表v9.6中添加了一个新的列 ALTER TABLE queries ADD COLUMN ml_partition_source UUID; 然后在另一个事务中,我执行了 ALTER TABLE queries ALTER COLUMN ml_partition_source SET DEFAULT public.gen_random_uuid(); 我在两个事务中这样做,因为在一个新列上设置默认值会导致Postgres重

最近,我在我的4000多万行Postgres表v9.6中添加了一个新的列

ALTER TABLE queries
   ADD COLUMN ml_partition_source UUID;
然后在另一个事务中,我执行了

ALTER TABLE queries
   ALTER COLUMN ml_partition_source
      SET DEFAULT public.gen_random_uuid();
我在两个事务中这样做,因为在一个新列上设置默认值会导致Postgres重写整个表,这可能需要几个小时,在生产中是不可接受的

现在,我想为添加新列之前存在的所有查询回填此列,而不锁定表。一种方法是使用CRUD API,但一些粗略的计算表明,这需要大约22天的时间,也许我的API性能可以提高,但这是一个完全不同的问题。相反,我尝试编写postgres函数:

CREATE OR REPLACE FUNCTION backfill_partition_source()
  RETURNS void AS $$
declare
  query_ record;
BEGIN
  for query_ in
  select * from api_mldata.queries where ml_partition_source is null
  loop
    update api_mldata.queries SET ml_partition_source = public.gen_random_uuid() where id = query_.id;
  end loop;
END;
$$ LANGUAGE plpgsql;
并使用选择回填分区源执行该操作;。但最终还是把桌子锁上了

如何在不影响生产或对生产影响最小的情况下回填柱

编辑:我的一个想法是将Postgres脚本分块,一次操作100k行或类似的内容,然后在循环中执行脚本。因此select语句将成为

select * from api_mldata.queries
where ml_partition_source is null
limit 100000;

你不能不锁门就离开,但是你可以把锁保持得相当短

与其在循环中运行多个单行更新,不如运行更大的更新:

UPDATE api_mldata.queries
SET ml_partition_source = DEFAULT
WHERE id BETWEEN 1 AND 999999;
这里id是表的主键

这样,您就可以进行一些更大的更新,每个更新针对不同的ID范围


为了避免膨胀和过度锁定,请在各自的事务中运行每个语句,并在语句之间的表上启动一个显式真空。

哦,太棒了!如果表的主键是UUID,您是否预计会出现任何问题?不,应该可以。您也不必使用主键——任何可以用来高效创建合理块的列都可以。