急!两个oracle数据库如何做数据交换
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了急!两个oracle数据库如何做数据交换相关的知识,希望对你有一定的参考价值。
有两个oracle数据库,表结构不一样,在A数据库里建了中间表,需要从中间表里取数据到B数据库,如何操作?
用数据库快照就能实现啊.Oracle快照原理及实现总结
Oracle数据库的快照是一个表,它包含有对一个本地或远程数据库上一个或多个表或视图的查询的结果。对于中大型数据库,业务数据库里所有的数据同步到另外一个处理服务器上最佳的选择还是使用SnapShot方式,即快照的方式。
由于工作需要,今天需要将业务数据库里所有的数据同步到另外一个处理服务器上。在做方案的时候,想了很多方法,当然最快的办法还是使用物理热备的方式。
但是我个人认为如果对于中大型数据库(我们的数据库有300G左右)最佳的选择还是使用SnapShot方式,即快照的方式。
Oracle数据库的快照是一个表,它包含有对一个本地或远程数据库上一个或多个表或视图的查询的结果。也就是说快照根本的原理就是将本地或远程数据库上的一个查询结果保存在一个表中。
以下是我建立的Snapshot,目的是从业务数据库上将数据Copy到处理数据库上,是不同的两个服务器之间对数据copy。
第一步:在处理服务器上的Oracle终端,建立database link,业务数据库服务器SID为TEST
create database link TEST_DBLINK.US.ORACLE.COM
connect to AMICOS identified by AMICOS
using 'test';
第二步:在业务数据库上对应的表建立快照日志
Create snapshot log on A_Table;
第三步:建立Snapshot 快照名称为:Test_SnapShot
Create snapshot Test_SnapShot
REFRESH COMPLETE START WITH SYSDATE NEXT SYSDATE+1/24
as select * from A_Table@TEST_DBLINK
说明:REFRESH是刷新方法
刷新方式有:COMPLETE和FAST两种,而START WITH是说明开始执行的时间。
Next是下次执行的时间
而AS以后是构成快照的查询方法。
相关的方法:
更改快照
ALTER SNAPSHOT Test_SnapShot
REFRESH COMPLETE START WITH SYSDATE NEXT SYSDATE+1/2;
手动刷新快照 在命令界面执行:
EXEC DBMS_SNAPSHOT.REFRESH('Test_SnapShot ','C');
第一个参数是要刷新的快照名
第二个参数是刷新的方式,F----FAST, C---COMPLETE
查看快照最后刷新的日期
SELECT NAME,LAST_REFRESH
FROM ALL_SNAPSHOT_REFRESH_TIMES;
最后非常的方案:
1:为需要做Snapshot的表建立Snapshot日志
create snapshot log on t1 with rowid; 这里使用ROWID建立日记的参数
2:采用Fast的方式建立快照,使用rowid做为参考参数
create snapshot fb_test_b refresh fast with rowid start with sysdate next sysdate+1/1440 as select * from fb_test_b@my_dblink;
最好能按照rowid来建立快照。要不然就必须要为表建立Primary Key。 参考技术A 在B库中建一个Database link 指向A库
就可以了.
create database link test connect to A用户名 identified 密码 using '指向A库的网络服务名' ;
insert into b表 as select * from a表@test;本回答被提问者采纳 参考技术B 我们以前是通过Java写了个程序,读取A数据库中的数据,通过一些逻辑处理生成insert语句的字符串,然后写在txt文档里面。
然后,跑到B数据库里执行这些insert语句啦。
当然,如果你可以同时连接A、B数据库,这边就不用写入txt文档,查出来的数据处理一下顺序啥的,直接插入到另外一个数据库。
你这边还做了个中间表,那处理顺序啥的就更简单了。
Oracle用分区表分区交换做历史数据迁移
一。
说明:
关于分区表很多其它内容: http://blog.csdn.net/tanqingru/article/category/1397435
关于表空间传很多其它内容: http://blog.csdn.net/tanqingru/article/category/1138527
二。
实例:
整个过程是在OLTP库做分区交换。然后通过表空间传输迁移至OLAP库。最后再做一次分区交换就可以。
1.创造须要的环境。
OLTP库环境准备:
SQL> conn /as sysdba Connected. SQL> select * from V$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production PL/SQL Release 11.2.0.3.0 - Production CORE 11.2.0.3.0 Production TNS for Linux: Version 11.2.0.3.0 - Production NLSRTL Version 11.2.0.3.0 - Production SQL> show parameter db_create_file_dest NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_create_file_dest string /data01/qing create tablespace tan_2013_9 datafile size 5m autoextend on; create tablespace tan_2013_10 datafile size 5m autoextend on; create tablespace tan_2013_11 datafile size 5m autoextend on; create tablespace tan_2013_12 datafile size 5m autoextend on; create tablespace tan_2014_1 datafile size 5m autoextend on; create tablespace tan_2014_2 datafile size 5m autoextend on; create tablespace tan_2014_3 datafile size 5m autoextend on; create tablespace tan_2014_4 datafile size 5m autoextend on; create tablespace tan_2014_5 datafile size 5m autoextend on; create tablespace tan_2014_6 datafile size 5m autoextend on; create tablespace tan_2014_7 datafile size 5m autoextend on; create tablespace tan_2014_8 datafile size 5m autoextend on; conn tan/tan SQL> create table tan (t_id number(10), t_name varchar2(100), t_date date ) partition by range(t_date) (partition tan_2013_9 values less than(to_date('2013-10-01','yyyy-mm-dd')) tablespace tan_2013_9, partition tan_2013_10 values less than(to_date('2013-11-01','yyyy-mm-dd')) tablespace tan_2013_10, partition tan_2013_11 values less than(to_date('2013-12-01','yyyy-mm-dd')) tablespace tan_2013_11, partition tan_2013_12 values less than(to_date('2014-01-01','yyyy-mm-dd')) tablespace tan_2013_12, partition tan_2014_1 values less than(to_date('2014-02-01','yyyy-mm-dd')) tablespace tan_2014_1, partition tan_2014_2 values less than(to_date('2014-03-01','yyyy-mm-dd')) tablespace tan_2014_2, partition tan_2014_3 values less than(to_date('2014-04-01','yyyy-mm-dd')) tablespace tan_2014_3, partition tan_2014_4 values less than(to_date('2014-05-01','yyyy-mm-dd')) tablespace tan_2014_4, partition tan_2014_5 values less than(to_date('2014-06-01','yyyy-mm-dd')) tablespace tan_2014_5, partition tan_2014_6 values less than(to_date('2014-07-01','yyyy-mm-dd')) tablespace tan_2014_6, partition tan_2014_7 values less than(to_date('2014-08-01','yyyy-mm-dd')) tablespace tan_2014_7, partition tan_2014_8 values less than(to_date('2014-09-01','yyyy-mm-dd')) tablespace tan_2014_8 ); create index ind_tan on tan(t_date) local ( partition ind_tan_2013_9 tablespace tan_2013_9, partition ind_tan_2013_10 tablespace tan_2013_10, partition ind_tan_2013_11 tablespace tan_2013_11, partition ind_tan_2013_12 tablespace tan_2013_12, partition ind_tan_2014_1 tablespace tan_2014_1, partition ind_tan_2014_2 tablespace tan_2014_2, partition ind_tan_2014_3 tablespace tan_2014_3, partition ind_tan_2014_4 tablespace tan_2014_4, partition ind_tan_2014_5 tablespace tan_2014_5, partition ind_tan_2014_6 tablespace tan_2014_6, partition ind_tan_2014_7 tablespace tan_2014_7, partition ind_tan_2014_8 tablespace tan_2014_8 ); begin for i in 1.. 10000 loop if( mod(i,12)+1 <=8) then insert into tan values(i,'tan'||i,to_date('2014-'||(mod(i,12)+1)||'-01','yyyy-mm-dd')); else insert into tan values(i,'tan'||i,to_date('2013-'||(mod(i,12)+1)||'-01','yyyy-mm-dd')); end if; end loop; commit; end; / SQL> select count(*) from tan partition(tan_2013_12) ; COUNT(*) ---------- 833 SQL> select count(*) from tan partition(tan_2013_9) ; COUNT(*) ---------- 833 SQL> select count(*) from tan partition(tan_2014_8) ; COUNT(*) ---------- 833 SQL> select count(*) from tan partition(tan_2014_1) ; COUNT(*) ---------- 833 SQL> select partition_name,tablespace_name from dba_segments where segment_name in ('TAN','IND_TAN'); PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ TAN_2014_8 TAN_2014_8 TAN_2014_7 TAN_2014_7 TAN_2014_6 TAN_2014_6 TAN_2014_5 TAN_2014_5 TAN_2014_4 TAN_2014_4 TAN_2014_3 TAN_2014_3 TAN_2014_2 TAN_2014_2 TAN_2014_1 TAN_2014_1 TAN_2013_9 TAN_2013_9 TAN_2013_12 TAN_2013_12 TAN_2013_11 TAN_2013_11 TAN_2013_10 TAN_2013_10 IND_TAN_2014_8 TAN_2014_8 IND_TAN_2014_7 TAN_2014_7 IND_TAN_2014_6 TAN_2014_6 IND_TAN_2014_5 TAN_2014_5 IND_TAN_2014_4 TAN_2014_4 IND_TAN_2014_3 TAN_2014_3 IND_TAN_2014_2 TAN_2014_2 IND_TAN_2014_1 TAN_2014_1 IND_TAN_2013_9 TAN_2013_9 IND_TAN_2013_12 TAN_2013_12 IND_TAN_2013_11 TAN_2013_11 IND_TAN_2013_10 TAN_2013_10 24 rows selected.
OLAP库环境准备
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">create tablespace tan_2013_7 datafile size 5m autoextend on;</span>
create tablespace tan_2013_8 datafile size 5m autoextend on; create table tan (t_id number(10), t_name varchar2(100), t_date date ) partition by range(t_date) (partition tan_2013_7 values less than(to_date('2013-08-01','yyyy-mm-dd')) tablespace tan_2013_7, partition tan_2013_8 values less than(to_date('2013-09-01','yyyy-mm-dd')) tablespace tan_2013_8 ); create index ind_tan on tan(t_date) local ( partition ind_tan_2013_7 tablespace tan_2013_7, partition ind_tan_2013_8 tablespace tan_2013_8 ); begin for i in 1.. 10000 loop insert into tan values(i,'tan'||i,to_date('2013-'||(mod(i,2)+7)||'-01','yyyy-mm-dd')); end loop; commit; end; / SQL> select count(*) from tan partition(tan_2013_8); COUNT(*) ---------- 5000 SQL> select count(*) from tan partition(tan_2013_7); COUNT(*) ---------- 5000
2.分区交换
如今要做的事是迁移2013年9月份数据。
创建个暂时表:
SQL> create table tmp_tan_2013_9 as select * from tan where 1=2;
SQL> create index ind_tmp_tan_2013_9 on tmp_tan_2013_9(t_date);
分区交换。
SQL> alter table tan exchange partition tan_2013_9
with table tmp_tan_2013_9 including indexes with validation;
验证:
SQL> select count(*) from tan partition(tan_2013_9) ;
COUNT(*) ---------- 0 SQL> select count(*) from tmp_tan_2013_9; COUNT(*) ---------- 833 SQL> select partition_name,tablespace_name from dba_segments where segment_name in ('TAN','IND_TAN'); PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ TAN_2014_8 TAN_2014_8 TAN_2014_7 TAN_2014_7 TAN_2014_6 TAN_2014_6 TAN_2014_5 TAN_2014_5 TAN_2014_4 TAN_2014_4 TAN_2014_3 TAN_2014_3 TAN_2014_2 TAN_2014_2 TAN_2014_1 TAN_2014_1 TAN_2013_12 TAN_2013_12 TAN_2013_11 TAN_2013_11 TAN_2013_10 TAN_2013_10 IND_TAN_2014_8 TAN_2014_8 IND_TAN_2014_7 TAN_2014_7 IND_TAN_2014_6 TAN_2014_6 IND_TAN_2014_5 TAN_2014_5 IND_TAN_2014_4 TAN_2014_4 IND_TAN_2014_3 TAN_2014_3 IND_TAN_2014_2 TAN_2014_2 IND_TAN_2014_1 TAN_2014_1 IND_TAN_2013_12 TAN_2013_12 IND_TAN_2013_11 TAN_2013_11 IND_TAN_2013_10 TAN_2013_10 22 rows selected.
3. 表空间传输:
很多其它关于表空间传输的内容:http://blog.csdn.net/bamuta/article/category/1138527验证表空间的自包括:
SQL> exec dbms_tts.transport_set_check(‘TAN_2013_9‘,TRUE);
PL/SQL procedure successfully completed.
SQL> select * from transport_set_violations;
no rows selected
另外表空间传输须要两端库的字符集一致。
导出无数据:
SQL> alter tablespace tan_2013_9 read only;
复制文件
[[email protected] ~]$ scp exp_tan_2013_9.dmp 192.168.114.174:/home/oracle/
[[email protected] ~]$ scp /data01/qing/QING/datafile/o1_mf_tan_2013_9tht2cgh_.dbf 192.168.114.174:/data01/vm603/VM603/datafile/
在目标库导入元数据
[[email protected] ~]$ imp \‘sys/oracle as sysdba\‘ transport_tablespace=y file=exp_tan_2013_9.dmp log=imp.log tablespaces=tan_2013_9 datafiles=‘/data01/vm603/VM603/datafile/o1_mf_tan_2013_9tht2cgh_.dbf‘
将两端库的该表空间read write
SQL> alter tablespace tan_2013_9 read write;
4.目标库再做分区交换
目标库对就表添加分区:SQL> alter table tan add partition tan_2013_9 values less than (to_date(‘2013-10-01‘,‘yyyy-mm-dd‘)) tablespace tan_2013_9;
Table altered.
SQL> select count(*) from tan partition(tan_2013_9);
COUNT(*)
----------
0
在目标库做一次分区交换。
SQL> alter table tan exchange partition tan_2013_9 with table tmp_tan_2013_9 including indexes with validation;
Table altered.
检查
SQL> select count(*) from tan partition(tan_2013_9); COUNT(*) ---------- 833 SQL> select table_name,partition_name,tablespace_name from user_tab_partitions; TABLE_NAME PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ ------------------------------ TAN TAN_2013_8 TAN_2013_8 TAN TAN_2013_7 TAN_2013_7 TAN TAN_2013_9 TAN_2013_9 SQL> select index_name,partition_name,tablespace_name from user_ind_partitions; INDEX_NAME PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ ------------------------------ IND_TAN IND_TAN_2013_8 TAN_2013_8 IND_TAN IND_TAN_2013_7 TAN_2013_7 IND_TAN TAN_2013_9 TAN_2013_9
5.源库删掉已经迁移走的分区:
SQL> select table_name,partition_name,tablespace_name from user_tab_partitions; TABLE_NAME PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ ------------------------------ TAN TAN_2014_3 TAN_2014_3 TAN TAN_2014_2 TAN_2014_2 TAN TAN_2014_4 TAN_2014_4 TAN TAN_2014_5 TAN_2014_5 TAN TAN_2014_6 TAN_2014_6 TAN TAN_2014_7 TAN_2014_7 TAN TAN_2014_8 TAN_2014_8 TAN TAN_2013_10 TAN_2013_10 TAN TAN_2013_11 TAN_2013_11 TAN TAN_2013_12 TAN_2013_12 TAN TAN_2014_1 TAN_2014_1 TAN TAN_2013_9 USERS 12 rows selected. SQL> <strong>alter table tan drop partition tan_2013_9;</strong> Table altered. SQL> select table_name,partition_name,tablespace_name from user_tab_partitions; TABLE_NAME PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ ------------------------------ TAN TAN_2014_3 TAN_2014_3 TAN TAN_2014_2 TAN_2014_2 TAN TAN_2014_4 TAN_2014_4 TAN TAN_2014_5 TAN_2014_5 TAN TAN_2014_6 TAN_2014_6 TAN TAN_2014_7 TAN_2014_7 TAN TAN_2014_8 TAN_2014_8 TAN TAN_2013_10 TAN_2013_10 TAN TAN_2013_11 TAN_2013_11 TAN TAN_2013_12 TAN_2013_12 TAN TAN_2014_1 TAN_2014_1
以上是关于急!两个oracle数据库如何做数据交换的主要内容,如果未能解决你的问题,请参考以下文章
oracle 中如何给空的数据行补零 如图(在线急等.大大们帮帮忙 谢咯)