数据库迁移

1.数据迁移的目的
使用 exp/imp 进行数据迁移的前置条件、操作步骤,降低对对应用造成的影响及避免故障

2.数据迁移的适用范围
所有线上库 9i ,10g > 11g 12c,11g 不建议用了

3.数据迁移的风险评估
1
1.exp导出数据时没有使用compress=n参数,会导致所有数据被压缩在一个extent里,导入可能由于没有连续的 blocks 满足需要,导致 imp 失败。
2
2.有些 os 对文件大小有限制,exp 数据时需要使用 filesize 参数来分割导出文件
3
3.exp 导出数据时没有正确估计 dmp 文件所需空间,导致主机磁盘满。
4
5.imp 导入数据时没有使用 ignore=y 参数,目标库上存在表的情况下数据无法导入
5
5.imp 导入大量数据时没有使用 commit=y 参数,导致事务太久,undo 资源占用过大无法及时回收。
6
6.跨字符集的数据迁移,由于字符集不兼容导致数据迁移失败。
7
7.imp 跨 schema 进行数据迁移时,没有正确指定 fromuser、touser,导致数据没有正确导入
8
8.导入表空间不存在或者空间不足,导致表创建失败或者数据导入失败,导致其他应用报错

4.数据迁移的准备工作
1
1.检查源数据库和目标库的版本、字符集,如果目标库版本低于源库,使用目标库的软件做导出。如果字符集不一致,不建议使用 exp/imp 迁移数据。
2
2.检查目标库上表结构和源结构是否一致,如果不一致,先修复结构,保证一致。
3
3.user_segments 里查出导出表所占的空间大小,检查 os 对文件大小的限制。如果表大小超出文件大小,exp导出时加上这两个参数:filesize=小于文件限制的数值m,file=exp01.dmp,exp02.dmp,…多个dmp文件
4
4.表比较多的情况下,建议用 parfile。各个参数在 parfile 里写好。
5
5.根据不同的需要要书写 query 子句时,这个参数跟 direct=y 冲突

5.数据迁移的执行过程
1
1)如果目标表是已存在数据,跟应用确认后,可以先进行导出备份,以防后面需要回退。
2
3
–1.按需求编辑exp参数文件
4
cat exp_scdb.par
5
userid=itpux/itpux@scdb
6
direct=y --直接路径导出,加快导出速度
7
compress=n --避免数据全部压缩在一个数据块上
8
file=exp_scdb.dmp
9
log=exp_scdb.log
10
recordlength=65535 --写dmp文件时一次IO的大小,上限是65535,可以加快导出速度
11
buffer=4096000 --数据缓冲区大小
12
tables=itpux01
13
14
exp parfile=exp_itpux.par --进行数据导出
15
16
–2.按需求编辑imp参数文件
17
cat imp_scdb.par
18
userid=itpux/itpux
19
commit=y --开启批量提交,避免长事务
20
ignore --如果目标表已经存在,只导入数据
21
buffer=100000 --大小控制导入速度的,设置过大会导致日志产生很快
22
fromuser=itpux
23
touser=itpux
24
tables=itpux01
25
file=imp_scdb.dmp
26
log=imp_scdb.log
27
28
imp parfile=imp_scdb.par --进行数据导入
29
30
注意:如果将表导入到两个schema:itpux01,itpux02,需将fromuser和touser一一对应,即使导出时只有一个schema
31
fromuser=itpux01,itpux02
32
touser=itpux01,itpux02
33
34
2)exp 导出数据时,检查exp的日志,如果报错,一般是参数配置错误,参考官方文档调整参数。
35
36
3)imp导入前,需要创建相应的用户,权限,表空间等对象,否则报错:
37
spool itpux_object_create_scripts.sql
38
SET LONG 2000000 PAGESIZE 0 head off verify off feedback off linesize 180
39
select dbms_metadata.get_ddl(‘USER’,‘ITPUX02’) from dual;
40
select dbms_metadata.get_granted_ddl(‘OBJECT_GRANT’,‘ITPUX02’) from dual;
41
select dbms_metadata.get_granted_ddl(‘ROLE_GRANT’,‘ITPUX02’) from dual;
42
select dbms_metadata.get_granted_ddl(‘SYSTEM_GRANT’,‘ITPUX02’) from dual;
43
select dbms_metadata.get_ddl(‘TABLESPACE’,‘ITPUX02’) from dual;
44
spool off;
45
46
4)imp导入数据过程,需要监控下数据库事务和日志产生速度。
47
48
5)对导入的表收集统计信息。
6.数据迁移后的验证方案
1
对比 exp、imp 的日志,确认导出导入数据量是否一致。并在数据库上检查数据量。
2
比如上面的数据迁移,检查数据量跟日志显示是否一致。
3
select count() from itpux.itpux01;
4
跨 schema 或者数据库迁移数据时,除检查日志外,还需要检查源和目标的对象数据量、是否有失效对象。
5
select object_type s_object_type,count(
) from dba_objects where owner=‘ITPUX01’ group by object_type ;
6
select object_type t_object_type,count() from dba_objects where owner=‘ITPUX01’ group by object_type ;
7
select * from dba_objects where status <> ‘VALID’ and owner=‘ITPUX01’;
8
9
–dblink两个库一起查询
10
select s.s_object_type, s.s_count, t.t_object_type, t.t_count
11
from (select object_type s_object_type, count(
) s_count from dba_objects@db01
12
where owner = ‘ITPUX01’ group by object_type) s,
13
(select object_type t_object_type, count() t_count from dba_objects where owner = ‘ITPUX01’
14
group by object_type) t;
15
16
自动生成编译无效对象 SQL 及编译过程
17
1)统计当前用户无效对象数量:
18
SQL> select owner,object_type,status,count(
) from dba_objects where status<> ‘VALID’ group by owner,object_type,status order by owner,object_type;
19
2)生成编译无效对象 SQL
20
SQL> select 'ALTER ’ || OBJECT_TYPE || ’ ’ || OWNER || ‘.’ || OBJECT_NAME || ‘COMPILE;’ from dba_objects where status <> ‘VALID’ and object_type in(‘PACKAGE’,‘PACKAGEBODY’,‘FUNCTION’,‘PROCEDURE’,‘TRIGGER’,‘VIEW’) ;
21
通过复制以上 SQL 语句,直接手动执行编译执行.
22
也可以采用如下方式在 oracle 用户下进行手工编译
23

su - oracle

24
$ sqlplus / as sysdba
25
SQL> @ O R A C L E H O M E / r d b m s / a d m i n / u t l r p . s q l 2627 如 果 有 序 列 要 处 理 28 e x c l u d e = S E Q U E N C E 29 目 标 库 30 方 法 1 : 311. 源 库 : 查 出 s e q u e n c e 的 最 大 值 322. 目 标 库 : D R O P S E Q U E N C E . . . . 再 C R E A T E S E Q U E N C E S T A R T 最 大 值 其 他 不 变 33 方 法 2 : 34 目 标 库 : D R O P S E Q U E N C E . . . . 再 C R E A T E S E Q U E N C E S T A R T 超 大 值 ( 保 证 比 之 35 前 的 都 大 , 不 会 发 生 冲 突 的 ) 36 可 以 用 以 下 脚 本 来 实 现 : 37 t t s c r e a t e s e q . s q l 38 s c r i p t f r o m t h e s o u r c e d a t a b a s e . U s e t h i s s c r i p t t o r e s e t t h e p r o p e r s t a r t i n g 39 v a l u e f o r s e q u e n c e s o n t h e t a r g e t d a t a b a s e . 40 c r t t s c r e a t e s e q . s q l 41 s e t h e a d i n g o f f f e e d b a c k o f f t r i m s p o o l o n e s c a p e o f f 42 s e t l o n g 1000 l i n e s i z e 1000 p a g e s i z e 043 c o l S E Q D D L f o r m a t A 30044 s p o o l t t s c r e a t e s e q . s q l 45 p r o m p t / ∗ = = = = = = = = = = = = = = = = = = = = = = = = = ∗ / 46 p r o m p t / ∗ D r o p a n d c r e a t e s e q u e n c e s ∗ / 47 p r o m p t / ∗ = = = = = = = = = = = = = = = = = = = = = = = = = ∗ / 48 s e l e c t r e g e x p r e p l a c e ( 49 d b m s m e t a d a t a . g e t d d l ( ′ S E Q U E N C E ′ , s e q u e n c e n a m e , s e q u e n c e o w n e r ) , 5 0 ′ . ∗ ( C R E A T E S E Q U E N C E . ∗ C Y C L E ) . ∗ ORACLE_HOME/rdbms/admin/utlrp.sql 26 27 如果有序列要处理 28 exclude=SEQUENCE 29 目标库 30 方法 1: 31 1.源库: 查出 sequence 的最大值 32 2.目标库: DROP SEQUENCE .... 再 CREATE SEQUENCE START 最大值 其他不变 33 方法 2: 34 目标库: DROP SEQUENCE .... 再 CREATE SEQUENCE START 超大值 (保证比之 35 前的都大,不会发生冲突的 ) 36 可以用以下脚本来实现 : 37 tts_create_seq.sql 38 script from the source database. Use this script to reset the proper starting 39 value for sequences on the target database. 40 cr_tts_create_seq.sql 41 set heading off feedback off trimspool on escape off 42 set long 1000 linesize 1000 pagesize 0 43 col SEQDDL format A300 44 spool tts_create_seq.sql 45 prompt /* ========================= */ 46 prompt /* Drop and create sequences */ 47 prompt /* ========================= */ 48 select regexp_replace( 49 dbms_metadata.get_ddl('SEQUENCE',sequence_name,sequence_owner), 50 '^.*(CREATE SEQUENCE.*CYCLE).* ORACLEHOME/rdbms/admin/utlrp.sql262728exclude=SEQUENCE29301:311.sequence322.DROPSEQUENCE....CREATESEQUENCESTART33234DROPSEQUENCE....CREATESEQUENCESTART353637ttscreateseq.sql38scriptfromthesourcedatabase.Usethisscripttoresettheproperstarting39valueforsequencesonthetargetdatabase.40crttscreateseq.sql41setheadingofffeedbackofftrimspoolonescapeoff42setlong1000linesize1000pagesize043colSEQDDLformatA30044spoolttscreateseq.sql45prompt/=========================/46prompt/Dropandcreatesequences/47prompt/=========================/48selectregexpreplace(49dbmsmetadata.getddl(SEQUENCE,sequencename,sequenceowner),50.(CREATESEQUENCE.CYCLE).’,
51
‘DROP SEQUENCE "’||sequence_owner||’"."’||sequence_name
52
||’";’||chr(10)||’\1;’) SEQDDL
53
from dba_sequences
54
where sequence_owner not in
55
(select name
56
from system.logstdby$skip_support
57
where action=0)
58
;
59
spool off

7.数据迁移核心对象风险
由于核心表访问、变更频繁,不宜直接使用 imp 对核心表大量导入数据。

8.数据迁移回退方案
exp 对应用无影响,不需要回退。
imp 后可能数据有误,需要进行回退操作。
如果目标表本来就是空表,跟应用确认后,直接清空即可。
如果目标表原有数据,跟应用确认是否使用原有备份数据进行恢复。若需要,先 exp备份当前数据,然后清空再导入前面的备份数据。

你可能感兴趣的:(数据库迁移)