在大量更新期间处理 Oracle ARCHIVELOG

Dealing with Oracle ARCHIVELOG during huge updates

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

update ANOTHER_TABLE set MY_META = 'HELLO'

每个 table.

估计总行数为 2e9

假设 ARCHIVELOG 模式打开,那么在这些更新期间,将消耗大量额外的 space。

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

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

有没有一种优雅的方法可以通过编程或调整来实现相同的目标"secret options"?

经过您的说明,我了解到:

  • 对于每个 table,您有一个值 MY_META,您希望将其作为 初始 值分配给每一行。
  • 您不介意删除 MY_META 并重新创建它。

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

缺点是 ALTER TABLE 命令虽然非常快,但会在您处理每个 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;