大规模更新期间处理Oracle ARCHIVELOG

时间:2018-08-08 05:40:09

标签: oracle sql-update oracle11gr2

需要在数据库中所有表的所有行中全局更新具有元数据的列。假设每个表格都有一列MY_META,目标大致是

update ANOTHER_TABLE set MY_META = 'HELLO'

每个表。

估计的总行数为2e9

假设ARCHIVELOG模式处于打开状态,那么在这些更新过程中将消耗大量额外空间。

计划将更新过程与业务事务同时在生产数据库中运行,这不应丢失。

最简单的方法是为ARCHIVELOG文件临时安装大量硬件。

是否有一种优雅的方法可以通过编程方式或通过调整“秘密选项”来实现相同的目标?

1 个答案:

答案 0 :(得分:1)

经过您的澄清,我了解到:

  • 对于每个表,您都有一个值MY_META想要作为 initial 值分配给每一行。
  • 您不介意丢弃MY_META并重新创建它。

在这种情况下,我建议您删除MY_META并使用默认值重新创建它。如果这样做,Oracle不会使用您的初始值来更新每条记录,并且重做的量将很小。

缺点是ALTER TABLE命令虽然很快,但是在处理每个表时会短暂地锁定每个表。还会使依赖MY_META列的软件包无效。

以下是该方法的演练,并附有评论:

-- Set up your current state
DROP TABLE my_big_table;
CREATE TABLE my_big_table (a number, my_meta varchar2(30) not null);
INSERT INTO my_big_table (a, my_meta) SELECT rownum, 'GARBAGE' FROM dual CONNECT BY rownum <= 100000;

-- Drop the my_meta column and replace it with one having a default value
ALTER TABLE my_big_table DROP COLUMN my_meta;
ALTER TABLE my_big_table ADD my_meta  varchar2(30) default 'INITIAL_VAL_FOR_TABLE' not null;

-- Look at my table -- you will see every row has your initial value
SELECT * FROM my_big_table;

-- Update some data
update my_big_table set my_meta = 'UPDATED_VALUE' WHERE a <= 15;

-- Look at my table -- you will see every row has your initial value except the first 15.
SELECT * FROM my_big_table order by a;