当前位置: 首页 > 面试题库 >

如何确保在要替换的表上进行同步DDL操作?

龙俊美
2023-03-14
问题内容

我有多个进程正在Redshift中不断刷新数据。他们开始一个事务,创建一个新表,COPY将来自S3的所有数据放入新表中,然后删除旧表并将新表重命名为旧表。

伪代码:

start transaction;
create table foo_temp;
copy into foo_temp from S3;
drop table foo;
rename table foo_temp to foo;
commit;

我用这种方式更新了几十个表。这很好用,但我想让多个进程执行这些表更新以达到冗余目的,并确保数据相当新鲜(不同的进程可以同时更新不同表的数据)。

除非一个进程尝试刷新另一个进程正在处理的表,否则它将正常工作。在这种情况下,第二个进程会被第一个进程阻塞,直到它提交为止,而在提交时,第二个进程则会收到错误消息:

错误:并发事务删除了表12345

我是否可以通过一种简单的方法来保证只有一个进程正在刷新表,以使第二个进程不会进入这种情况?

我考虑为每个真实表创建一个特殊的锁定表。在处理LOCK伴随实表之前,该过程将使用特殊锁表。我认为可以,但是我想避免为每个表创建一个特殊的锁定表。


问题答案:

您需要通过以下方式保护读者,防止其掉落:

  • begin transaction
  • rename main table to old_main_table
  • rename tmp table to main table
  • commit
  • drop table old_main_table
    Conn #1         Conn #2
    --------------  ------------------------------------------
                    > create table bar (id int,id2 int,id3 int);
                    CREATE TABLE
    > begin;
    BEGIN
                    > begin;
                    BEGIN
                    > alter table bar rename to bar2;
                    ALTER TABLE
    > select * from bar;  
                    > create table bar (id int,id2 int,id3 int,id4 int);
                    CREATE TABLE
                    > commit; drop table bar2;
                    COMMIT
    id | id2 | id3 
    ----+-----+-----
    (0 rows)
    > commit;
    COMMIT
                    DROP TABLE


 类似资料:
  • 问题内容: 我指的是此处提出的问题,并使用作者代码示例,现在我的问题是 作者为什么要使用,真的有必要吗,因为syncedMap始终会确保没有两个线程试图对其进行操作,那么为什么需要在该地图本身上进行操作呢? 非常感谢您的解释。 问题答案: 为什么我们需要对其本身进行同步? 您可能需要在一个已经同步的集合上进行同步,因为您正在对该集合执行两个操作-在您的示例中,是a 然后是a。您试图在 _调用_集合

  • 问题内容: 我正在用Java编写多线程应用程序,以提高顺序版本的性能。它是针对0/1背包问题的动态编程解决方案的并行版本。我有一个Intel Core 2 Duo,在不同的分区上都具有Ubuntu和Windows 7 Professional。我在Ubuntu中运行。 我的问题是并行版本实际上比顺序版本花费的时间更长。我认为这可能是因为所有线程都被映射到同一个内核线程,或者它们被分配给了同一个内核

  • 问题内容: 我有一类通用的代码是线程安全的。 该类中的方法之一是抽象的,需要针对不同的实现重写。 我需要确保或至少向其他开发人员标记此方法的所有实现都必须是线程安全的。 做这个的最好方式是什么? 是否有关键字或注释可达到此目的? 我已经尝试过了,但是不允许使用关键字组合。 问题答案: 您不能直接这样做。您可以做的一件事是将方法具体化,但是调用一个抽象方法: 这样,doFoo()将始终*在foo()

  • 这个问题类似于如何运行github操作步骤,即使前一步失败,但仍然无法完成作业,但接受的答案对我没有帮助,因为它会创建一个额外的作业。 下面我要做的是 当测试应用程序(步骤2)通过时;测试清理步骤应该运行,github操作工作流返回成功 当测试应用程序(步骤2)失败时;应运行测试清洁、行动松弛和失败行动步骤。github操作工作流返回失败 我如何修复下面的代码来实现它?

  • 如何在将GUI保持为活动状态而不是Hibernate/等待状态的同时延迟进程或创建队列?

  • 问题内容: 在写这个问题之前,我已经 有使用Affine转换的经验 阅读Quartz 2D编程指南中的Transforms文档 看过这个详细的CALayer教程 从Github 下载并运行LayerPlayer项目 但是,我仍然难以理解如何在 图层 上进行基本转换。寻找用于平移,旋转和缩放的解释和简单示例非常困难。 今天,我终于决定坐下来,进行测试项目,然后找出答案。我的答案如下。 笔记: 我只做