【问题标题】:How can I ensure synchronous DDL operations on a table that is being replaced?如何确保对被替换的表进行同步 DDL 操作?
【发布时间】:2014-01-08 15:50:50
【问题描述】:

我有多个进程不断刷新 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 特殊锁定表。我认为这可行,但我想避免为我的每个表创建一个特殊的锁表。

【问题讨论】:

标签: amazon-redshift


【解决方案1】:

您需要保护读者不被看到,这样做:

  • 开始交易
  • 将主表重命名为 old_main_table
  • 将 tmp 表重命名为主表
  • 提交
  • 删除表 old_main_table
康恩 #1 康恩 #2 -------------- ------------------------------------ ------ > 创建表格栏 (id int,id2 int,id3 int); 创建表 > 开始; 开始 > 开始; 开始 > 更改表栏重命名为 bar2; 更改表 > 从栏中选择 *; > 创建表格栏 (id int,id2 int,id3 int,id4 int); 创建表 > 提交;删除表栏2; 犯罪 编号 | id2 | id3 -+-----+-- (0 行) > 提交; 犯罪 删除表

【讨论】:

  • 因为只有当前会话会到达 target_old 表。如果 drop table 命令是在 commit 命令之后还是之前,了解它的重要性是非常有趣的?
  • @AvivNoy 答案与Redshift docs on Isolation 中的这一行有关:“系统目录表 (PG) 和其他 Amazon Redshift 系统表(STL 和 STV)未锁定在事务中;因此,更改从 DDL 和 TRUNCATE 操作产生的数据库对象在提交到任何并发事务时都是可见的。”重命名和删除是 AFAICT,不是事务的一部分,并且立即可见。 COMMIT 后 DROP 确保没有其他连接对表有未完成的引用。
猜你喜欢
  • 1970-01-01
  • 2017-09-09
  • 2018-05-08
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
相关资源
最近更新 更多