我在查看一些存储库时进入了这段代码,我知道锁的作用,还知道 Redshift 有一种方法在使用快照的查询之间维护表的当前版本。 那么问题是,事务开始时的锁定有意义吗? 我认为它带来的锁定用户的问题多于解决方案。 谢谢!
begin transaction;
lock ${rsDestination};
create temp table stage (like ${rsDestination});
insert into stage
(${_.join(_.keys(schema), ', ')})
values ${formattedRecords.join(',\n')};
delete from ${rsDestination}
using stage
where ${_.join(_.map(primaryKeys, (key) => `${rsDestination}.${key} = stage.${key}`), ' AND ')};
insert into ${rsDestination}
select * from stage;
end transaction;
drop table stage;`;
对该行的评论没有明显的问题,我想知道我是否遗漏了一些东西。 谢谢!
我对这段代码持保留态度——这里有一个超出锁范围的问题。见下文。
如您所见,此代码不需要锁。它很可能是通过为其他可能需要的人复制代码而到达这里的。这样做是为了停止 ETL 代码中的依赖循环。这是一种 hack,防止这些问题的最佳方法是设计没有并发循环的 ETL 代码。
在此代码中,源是 VALUES() 语句,它不能成为依赖循环的一部分。这不好,可能只会减慢集群上的其他查询。此代码中只有 1 个永久表,因此不可能出现循环。
现在讨论此代码的另一个问题:使用 VALUES() 插入数据。很少对 10 行数据执行此操作是可以的,它很小且不频繁。对任何大小的数据或大数据块频繁执行此操作都是集群杀手。这通过查询编译器推送数据来加载领导节点。它受到语句字符限制(64K)的限制,因此是错误的来源。只是不要这样做。使用 S3 中的副本。