ORACLE-数据抽取及备份
说明
本篇博文乃实战干货,转载请注明出处。
1、每周六 23:00,job调用存储过程,按日期备份 核心库 的B1、B2、B3、B4表,备份格式为:表名+_系统日期。
2、每周日 01:00,job调用物化视图,从 前置库 抽取数据到核心库。
3、以后针对历史数据,找到其对应的日期备份表即可。
一、授权
使用管理员给SJSJZX用户授予(create any table、create any procedure)权限:
grant create any table to SJSJZX;
grant create any procedure to SJSJZX;
执行结果
二、在核心库创建 dblink sjrkk_link,指向前置人口库:
先授权:
grant create database link to sjsjzx;
create public database link sjrkk_link connect to sjrkk02 IDENTIFIED BY sjrkk02
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.xxxx.xxxx)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)';
指定用户名和密码都为sjrkk02,连接的服务实例为orcl,指定的前置机ip地址192.168.xxxx.xxxx
三、在前置机上执行:
CREATE MATERIALIZED VIEW LOG ON T_FWGLXX WITH Rowid;
CREATE MATERIALIZED VIEW LOG ON T_FWJBXX WITH Rowid;
CREATE MATERIALIZED VIEW LOG ON T_RJBXX WITH Rowid;
CREATE MATERIALIZED VIEW LOG ON T_FWK WITH Rowid;
执行结果如下:
说明:物化视图的复制默认是基于主键的,也可以基于rowid,这里是create materialized view log on (主表名) with rowid,这样创建物化视图就要对应的加上with rowid。
四、在核心数据库中执行创建物化视图语句,每周日凌晨01:00执行从前置库抽取数据
CREATE MATERIALIZED VIEW T_FWGLXX REFRESH FAST with rowid NEXT NEXT_DAY(TRUNC(SYSDATE), '星期日')+1/24 AS SELECT * FROM T_FWGLXX @SJSJZX_LINK;
CREATE MATERIALIZED VIEW T_FWJBXX REFRESH FAST with rowid NEXT NEXT_DAY(TRUNC(SYSDATE), '星期日')+1/24 AS SELECT * FROM T_FWJBXX@SJSJZX_LINK;
CREATE MATERIALIZED VIEW T_RJBXX REFRESH FAST with rowid NEXT NEXT_DAY(TRUNC(SYSDATE), '星期日')+1/24 AS SELECT * FROM T_RJBXX@SJSJZX_LINK;
CREATE MATERIALIZED VIEW T_FWK REFRESH FAST with rowid NEXT NEXT_DAY(TRUNC(SYSDATE), '星期日')+1/24 AS SELECT * FROM T_FWK@SJSJZX_LINK;
说明:fast: 增量刷新,假设前一次刷新的时间为t1,那么使用fast模式刷新物化视图时,只向视图中添加t1到当前时间段内,主表变化过的数据。为了记录这种变化,建立增量刷新物化视图需要一个物化视图日志表(步骤已经创建)。
查看已经创建成功的物化视图
这样看和其他的表看不出来什么区别,用toad 看,区别就出来了(物化视图前面有个照相机的图标)
说明:物化视图不同于普通视图,物化视图对于前台数据库使用者来说如同一个实际的表,具有和一般表相同的如select等操作,而其实际上是一个视图,一个由系统实现定期刷新其数据的视图(具体刷新时间在定义物化视图的时候已有定义),使用物化视图更可以实现视图的所有功能,而物化视图却不是在使用时才读取,大大提高了读取速度,特别适用抽取大数据量表某些信息以及数据链连接表使用,但是物化视图占用数据库磁盘空间。
五、在核心库中创建存储过程,用于备份前置机中B1、B2、B3、B4库,备份格式为:表名+_系统日期
CREATE OR REPLACE PROCEDURE proc_bak_rkk
IS
--定义日期变量
v_date VARCHAR2 (8);
--定义动态sql
v_sql1 VARCHAR2 (2000);
v_sql2 VARCHAR2 (2000);
v_sql3 VARCHAR2 (2000);
v_sql4 VARCHAR2 (2000);
--定义动态表名
v_tb1 VARCHAR2 (40);
v_tb2 VARCHAR2 (40);
v_tb3 VARCHAR2 (40);
v_tb4 VARCHAR2 (40);
BEGIN
--取日期变量
SELECT TO_CHAR (SYSDATE, 'yyyymmdd') INTO v_date FROM DUAL;
--为动态表命名
v_tb1 := 'T_FWGLXX_' || v_date;
v_tb2 := 'T_FWJBXX_' || v_date;
v_tb3 := 'T_RJBXX_' || v_date;
v_tb4 := 'T_FWK_' || v_date;
v_sql1 := 'create table ' || v_tb1 || ' as select * from T_FWGLXX';
v_sql2 := 'create table ' || v_tb2 || ' as select * from T_FWJBXX';
v_sql3 := 'create table ' || v_tb3 || ' as select * from T_RJBXX';
v_sql4 := 'create table ' || v_tb4 || ' as select * from T_FWK';
--执行动态sql
EXECUTE IMMEDIATE v_sql1;
EXECUTE IMMEDIATE v_sql2;
EXECUTE IMMEDIATE v_sql3;
EXECUTE IMMEDIATE v_sql4;
END proc_bak_rkk;
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT
(
job => X
,what => 'SJSJZX.PROC_BAK_RKK;'
,next_date => to_date('07/09/2016 23:00:00','mm/dd/yyyy hh24:mi:ss') --'07/09/2016 23:00:00'开始执行时间
,interval => 'TRUNC(next_day(sysdate,7))+23/24'
,no_parse => FALSE
);
:JobNumber := to_char(X);
END;
以上内容为实战中总结的数据库级的数据备份和抽取,转载请注明出处。