我有这个业务需求,我们需要将数据从Hadoop导出到Oracle,因为sqoop无法有效处理以覆盖模式导出的删除操作。为了保持最短的停机时间,我们开发了一个流程(写为存储过程),该流程按顺序执行以下步骤:
创建了STG_TABLES(作为登台表)和FINAL_TABLES。
一旦sqoop将数据导出到stg_tables。
final_tables
重命名(假设我们上次运行的final_tables中有数据)重命名为temp_tables
stg_tables
重命名为final_tables
temp_tables
重命名为stg_tables
并被截断(使它们为下一次新导出做好准备)。 您是否有更好的想法/建议来改进上述过程?
请提出建议。
谢谢!
最佳答案
根据需要定义FINAL
表,并添加一个技术列load_date
或DATE
类型。
例:
create table FINAL_TABLES
(load_date DATE,
col1 varchar2(10));
使用
STG
定义具有相同结构的interval partitioning
表create table STG_TABLES
(load_date DATE,
col1 varchar2(10))
PARTITION BY RANGE (load_date)
INTERVAL(NUMTODSINTERVAL(1, 'DAY'))
(
PARTITION p_init VALUES LESS THAN (TO_DATE('15-03-2020', 'DD-MM-YYYY'))
);
现在,执行
sqoop
装载填充STG
表中的数据。 load_date
是加载的时间戳,在所有行中均相等。使用
insert
模拟的示例insert into STG_TABLES (load_date, col1)
values (sysdate,'new load');
commit;
在下一步中,使用
STG
交换FINAL
和exchange partition
表的内容alter table STG_TABLES
exchange partition FOR (to_date('2020-03-15 05:55:00','yyyy-mm-dd hh24:mi:ss'))
with table FINAL_TABLES
without validation;
STG
表的分区由当前load_date
值标识现在,已加载的数据在
FILNAL
表中,并且STG
表包含FINAL
表的先前状态。您可以通过删除分区来摆脱它,可以在下一次加载之前立即完成。后一个选项可以帮助进行故障排除。
alter table STG_TABLES
drop partition FOR (to_date('2020-03-15 05:55:00','yyyy-mm-dd hh24:mi:ss'));
最后说明
FINAL
表的使用者而言,此选项要好得多,因为该表一直存在,因此查询不会因RENAME
而无效。如果在下一次加载之前推迟
DROP PARTITION
,则即使在加载期间长时间运行的查询也可以保留下来,并在STG
表的各段上继续进行。 FINAL
表具有索引,则在STG
上将相同的索引结构定义为LOCAL
索引。加载后检查
STG
表是否所有索引均有效将
INCLUDING INDEXES
添加到交换分区语句。 简单定义未分区的
STG
表和已分区的FINAL
表。 上面的示例每天可处理一次增量负载-针对不同的频率调整INTERVAL模式。