gpt4 book ai didi

sql - 为什么在 RedShift 中的事务结束之前释放隐式表锁?

转载 作者:行者123 更新时间:2023-12-01 02:20:28 24 4
gpt4 key购买 nike

我有一个 ETL 过程,它在 RedShift 中以增量方式构建维度表。它按以下顺序执行操作:

  • 开始交易
  • 创建一个表 staging_foo 像 foo
  • 将数据从外部源复制到 staging_foo
  • 对 foo 执行批量插入/更新/删除,使其匹配 staging_foo
  • 删除 staging_foo
  • 提交交易

  • 这个过程单独工作,但为了实现连续流刷新到 foo和发生故障时的冗余,我有多个同时运行的进程实例。当这种情况发生时,我偶尔会遇到并发序列化错误。这是因为两个进程都在重播对 foo 的一些相同更改。来自 foo_staging在重叠交易中。
    发生的情况是第一个进程创建了 staging_foo表,第二个进程在尝试创建同名表时被阻塞(这就是我想要的)。当第一个进程提交其事务(可能需要几秒钟)时,我发现第二个进程在提交完成之前被解除阻塞。所以它似乎正在获取 foo 的快照提交之前的表,这会导致插入/更新/删除(其中一些可能是多余的)失败。
    我正在根据文档进行理论化 http://docs.aws.amazon.com/redshift/latest/dg/c_serial_isolation.html它说:

    Concurrent transactions are invisible to each other; they cannot detect each other's changes. Each concurrent transaction will create a snapshot of the database at the beginning of the transaction. A database snapshot is created within a transaction on the first occurrence of most SELECT statements, DML commands such as COPY, DELETE, INSERT, UPDATE, and TRUNCATE, and the following DDL commands :

    ALTER TABLE (to add or drop columns)

    CREATE TABLE

    DROP TABLE

    TRUNCATE TABLE


    上面引用的文档让我有些困惑,因为它首先说将在事务开始时创建快照,但随后说仅在某些特定 DML/DDL 操作第一次出现时创建快照。
    我不想在替换 foo 的地方做深拷贝而不是逐步更新它。我有其他进程会不断查询此表,因此我永远不会有时间可以不间断地替换它。另一个问题对深复制提出了类似的问题,但对我不起作用: How can I ensure synchronous DDL operations on a table that is being replaced?
    有没有办法让我以一种可以避免并发序列化错误的方式执行我的操作?我需要确保对 foo 具有读访问权限所以我不能 LOCK那张 table 。

    最佳答案

    好的,Postgres(因此 Redshift [或多或少])使用 MVCC (Multi Version Concurrency Control)用于事务隔离而不是 db/table/row/page locking model (as seen in SQL Server 、MySQL 等)。简单地说,每个事务都对数据进行操作 因为它在事务开始时存在 .

    所以你的评论“我有几个同时运行的进程实例”解释了这个问题。如果进程 2 在进程 1 运行时启动,则进程 2 无法看到进程 1 的结果。

    关于sql - 为什么在 RedShift 中的事务结束之前释放隐式表锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20863224/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com