Oracle小库利用导出导入迁移数据库实战

1.基本信息

源库目标库
IP192.168.0.6192.168.0.8
数据库版本19C19C

2.提前作业部分

以导出导入方式迁移数据库需要预约停机,为节省停机时间,可以提前做一部分工作。

2.1.创建表空间

表空间名和大小最好和源库一样,停机作业当天再检查一遍,防止中间源库扩充表空间而目标库没有扩。

2.2.创建 Role 和 Profile

提前把 role 和 profile 创建好,避免导入 owner 报错。

2.3.安装 ogg 软体

源库有 ogg ,提前安装好 ogg

create tablespace ggs_data datafile '/data/monkey/ggs_data01.dbf' size 1g;
create user ogg identified by ogg default tablespace ggs_data temporary tablespace temp quota unlimited on ogg;
grant connect, resource,dba TO ogg;

dblogin userid ogg,password ogg
add checkpointtable ogg.checkpointtab
2.4.提前建立 OS 排程脚本

execute_oracle_procedure.sh

3.保存失效对象

@TOSOURCE 代表的是在目标库建立的指向源库的 DBLINK,在目标库执行。

create table monkey.invalid_objects as select owner,object_name,object_type From dba_objects@TOSOURCE where status = 'INVALID';

4.锁账号

源库锁账号,防止新数据进入,根据实际情况锁,例如你已经知道要导哪些 OWNER 了,直接锁定即可。

-- 这个 sql 是在目标库执行的,得到的脚本在源库执行锁账号
SELECT 'ALTER  USER ' || USERNAME || ' ACCOUNT LOCK;'
  FROM (SELECT USERNAME FROM dba_users@TOSOURCE
        MINUS
        SELECT USERNAME FROM dba_users)
 WHERE USERNAME NOT IN ('OGG', 'MONITOR');

5.停 OS 排程和数据库 JOB

源库停 OS 排程和数据库 JOB,防止新数据进入。

# 停 OS 排程
crontab -l > crontab_backup.txt
crontab -l | sed '/^$/! s/^/#/' | crontab -
scp crontab_backup.txt 192.168.0.8:`pwd`
-- 记录下来 JOB_QUEUE_PROCESSES 的值,后面作业完源库需要改回去
show parameter JOB_QUEUE_PROCESSES;
alter system set JOB_QUEUE_PROCESSES=0;

6.停 OGG

源库停 OGG,rep1 是应用进程,ext1 是抽取进程,pub1 是传送进程。把 info 信息记录下来,后面新增 OGG 时需要用到。

stop rep1
stop ext1
stop pub1
info rep1
info ext1
info ext1

7.杀 session

源库杀 session,把自己排除,别把自己的会话也杀了。

select 'alter system kill session '''||sid||','||serial#||''' immediate;'From v$session where type='USER' and username <>'MONKEY';

8.导出

源库根据实际情况导出(按照自己的 owner 清单)

SELECT LISTAGG (USERNAME, ',') WITHIN GROUP (ORDER BY USERNAME) AS result
  FROM (SELECT USERNAME FROM dba_users@TOSOURCE
        MINUS
        SELECT USERNAME FROM dba_users)
 WHERE USERNAME NOT IN ('OGG', 'MONITOR');
create directory monkey as '/data/monkey/20250420';
alter system set parallel_max_servers=30;
cd /data/monkey/20250420
vi expdp_monkey_schemas.par
directory=monkey
SCHEMAS=SAILY,JOHN,HR,MONKEY
dumpfile=expdp_monkey_schemas_%U.dmp
filesize=6G
CONTENT=ALL
parallel=10
COMPRESSION=ALL
logfile=expdp_monkey_schemas.log
expdp monkey/monkey PARFILE=expdp_monkey_schemas.par
scp expdp_monkey_schemas_*.dmp oracle@192.168.0.8:/data/monkey/20250420

9.导入结构

目标库导入结构

create directory monkey as '/data/monkey/20250420';
alter system set parallel_max_servers=30;
cd /data/monkey/20250420
-- monkey是我的管理账号,目标库我创建了,但是为了保持一致,还是准备从源库导入
sqlplus / as sysdba
drop user monkey cascade;
# 可以执行两次,防止第一次用户不存在导致导入缺失
impdp \'/ as sysdba\' directory=monkey  dumpfile=expdp_monkey_schemas_%U.dmp CONTENT=METADATA_ONLY EXCLUDE=STATISTICS  parallel=10 logfile=impdp_expdp_monkey_schemas.log 
# 下面的语句也是为了防止用户不存在导致的赋权缺失
impdp \'/ as sysdba\' directory=monkey  dumpfile=expdp_monkey_schemas_%U.dmp  parallel=10 INCLUDE=GRANT logfile=impdp_GRANT_monkey_schemas.log

结构导入之后,要进行比对,别导少了。

DECLARE
    -- 定义一个嵌套表类型
    TYPE OwnerArray IS TABLE OF VARCHAR2(30);

    -- 初始化你的owner列表
    owners OwnerArray := OwnerArray('MONKEY', 'SAILY', 'JOHN','HR');

    v_owner        VARCHAR2(30);
    v_count_local  NUMBER;
    v_count_remote NUMBER;
BEGIN
    -- 遍历数组
    FOR i IN owners.FIRST .. owners.LAST LOOP
        v_owner := owners(i);

        -- 查询本地(B库)对象数
        SELECT COUNT(*)
        INTO v_count_local
        FROM dba_objects
        WHERE owner = v_owner;

        -- 查询远程(A库,通过DBLINK)对象数
        SELECT COUNT(*)
        INTO v_count_remote
        FROM dba_objects@TOSOURCE -- <--- 替换成你的DBLINK名字
        WHERE owner = v_owner;

        -- 比较并输出结果
        IF v_count_local = v_count_remote THEN
            DBMS_OUTPUT.PUT_LINE('Owner ' || v_owner || ' OK: ' || v_count_local || ' objects.');
        ELSE
            DBMS_OUTPUT.PUT_LINE('Owner ' || v_owner || ' DIFFERENT! Local=' || v_count_local || ', Remote=' || v_count_remote);
        END IF;
    END LOOP;
END;
/

10.禁用触发器和外键

目标库禁用触发器和外键,防止数据导入时报错。

-- 禁用外键
select 'ALTER TABLE '||OWNER||'.'||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';' from DBA_CONSTRAINTS where constraint_type='R' and owner in ('MONKEY', 'SAILY', 'JOHN','HR');
-- 禁用触发器
select 'ALTER TRIGGER '||OWNER||'.'||TRIGGER_NAME||' DISABLE;' from dba_triggers where TABLE_OWNER in ('MONKEY', 'SAILY', 'JOHN','HR');

11.导入数据

目标库导入数据,注意归档,TEMP 表空间,UNDO 表空间,在线日志。

# 把 undo 保留时间改小,防止 undo 不足
alter system set undo_retention=60;
impdp \'/ as sysdba\' directory=monkey  dumpfile=expdp_monkey_schemas_%U.dmp CONTENT=DATA_ONLY  parallel=10 logfile=impdp_DATA_ONLY_monkey_schemas.log;
# 把之前修改的参数改回去
alter system set undo_retention=900;
alter system set parallel_max_servers=0;

12.启用外键和触发器

select 'ALTER TABLE '||OWNER||'.'||TABLE_NAME||' ENABLE CONSTRAINT '||CONSTRAINT_NAME||';' from DBA_CONSTRAINTS where constraint_type='R' and owner in ('MONKEY', 'SAILY', 'JOHN','HR');
select 'ALTER TRIGGER '||OWNER||'.'||TRIGGER_NAME||' ENABLE;' from dba_triggers where TABLE_OWNER in ('MONKEY', 'SAILY', 'JOHN','HR');

13.解锁账号

源库导出结构的时候账号是锁定状态,所以目前目标库的账号也是锁定状态,要解锁。

ALTER  USER MONKEY ACCOUNT UNLOCK;
ALTER  USER SAILY ACCOUNT UNLOCK;

14.关闭 OGG 传送进程

在第6步停 OGG 的时候,有一个 rep1 的应用进程,这个进程应用的 trail 文件来自于 192.168.0.10,关闭 192.168.0.10上的传送进程

stop e_monkey
stop p_monkey

15.处理 IP

因为要保持迁移后程序不需要修改 TNS ,因此我们要把源库和目标库的 IP 调换。

涉及到以下部分:

源库和目标库的 listener.ora文件

源库和目标库的 /etc/hosts 文件

如果有高可用,需要修改高可用的 IP 资源

16.OGG 处理

目标库目前是没有 OGG 进程的,因此要新增

16.1. 目标库应用进程

对于目标库上面的应用进程,只需要把源库参数文件和 trail 文件 SCP 过来,新增即可。

# 把参数文件和 trail 文件 scp 过来
scp -r monkey 192.168.0.6:`pwd`
scp ./dirprm/rep1.prm 192.168.0.6:/data/ogg/dirprm
# 添加应用进程
add replicat rep1,exttrail ./monkey/r1,checkpointtable ogg.checkpointtab
# 这里的324和313206553就是第6步停 rep1 时候 info 得到的
alter replicat rep1,EXTSEQNO 324,EXTRBA 313206553
start rep1 NOFILTERDUPTRANSACTIONS
16.2.目标库抽取传送进程

对于目标库上的抽取进程和传送进程,把源库的参数文件 SCP 过来,新增进程。注意,此时会在 192.168.0.12 (应用目标库抽取的 trail 文件的主机)上的 OGG需要重新指定 exttrail

首先停止 192.168.0.12 上的应用进程

stop r_monkey

目标库(192.168.0.8 )新增抽取和传送进程

dblogin userid ogg,password ogg
add extract ext1,integrated tranlog,begin now
register extract ext1 database
# 注意 ext1.prm 中的 EXTTRAIL 参数要修改为e2,不要用原来的e1
ADD EXTTRAIL ./monkey/e2, EXTRACT bd_ext, MEGABYTES 100

add extract pub1, exttrailsource ./monkey/e2
# 注意 pub1.prm 中的 RMTTRAIL 参数要修改为r2,不要用原来的r1
add rmttrail ./monkey/r2, extract pub1

start ext1
start pub1
16.3.应用目标库传送过来trail文件的应用进程

应用目标库抽取的 trail 文件的主机(192.168.0.12 )修改应用进程

ALTER REPLICAT r_monkey, EXTTRAIL ./monkey/r2, EXTSEQNO 0, EXTRBA 0
start monkey
16.4.开启抽取和传送进程

开启 192.168.0.10(即目标库 rep1 应用 trail文件来源主机) 上的抽取和传送进程

start e_monkey
start p_monkey

17.新建OS排程

目标库目前是没有 OS 排程的,利用从源库传送过来的 crontab 备份文件进行恢复。如果有高可用的话,每个节点都要执行。

cd ~
crontab crontab_backup.txt
crontab crontab_backup.txt

18.检查 DBLINK 及其连通性

把源库的 tnsnames.ora 文件 SCP 到目标库

scp tnsnames.ora 192.168.0.8:`pwd`

19.文件比对

如果有高可用,需要确保每个节点的 tnsnames.ora listener.ora spfile orapwd 文件一样。

20.全库编译

全库编译后,与第3步保存的失效对象进行对比

cd $ORACLE_HOME/rdbms/admin
@utlrp.sql

21.全库收集统计信息

BEGIN
	DBMS_STATS.gather_database_stats;
END;
/

22.其他

如果源库还用,需要关闭并行,改回 JOB_QUEUE_PROCESSES 和 parallel_max_servers 参数,解锁账号。

目标库测试 OGG 应用是否正常(增删一笔试试)

目标库看 OS 排程执行是否正常,是否有执行日志产生

目标库看是否有失效的索引

目标库的监控是否安装,是否正常

目标库的备份配置是否正常,归档目录是否足够,归档删除排程是否正常,最好做一次全备。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值