需要在数据库中所有表的所有行中全局更新具有元数据的列。假设每个表格都有一列MY_META
,目标大致是
update ANOTHER_TABLE set MY_META = 'HELLO'
每个表。
估计的总行数为2e9
。
假设ARCHIVELOG模式处于打开状态,那么在这些更新过程中将消耗大量额外空间。
计划将更新过程与业务事务同时在生产数据库中运行,这不应丢失。
最简单的方法是为ARCHIVELOG文件临时安装大量硬件。
是否有一种优雅的方法可以通过编程方式或通过调整“秘密选项”来实现相同的目标?
答案 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;