暂无图片
暂无图片
5
暂无图片
暂无图片
暂无图片

3000字详解:Oracle 19c 数据泵恢复实战经验分享

原创 vic 2024-12-12
739

本文会从环境准备开始,包括创建可插拔数据库(PDB)、表空间的创建与管理、用户账号的配置、字符集的调整,一直到数据导入的具体步骤,另外还会分享一些导入时常见问题解决。希望通过这些经验和技巧,能让在处理类似任务时有到启发。

一、环境准备

(一)创建pdb

首先准备环境,创建pdb,用于恢复

-- 使用克隆模式 创建 PDB CREATE PLUGGABLE DATABASE [PdbName] ADMIN USER [AdminUser] IDENTIFIED BY [AdminPaswd] FILE_NAME_CONVERT=('[/data/oracle/ORADB/pdbseed/]', '[/data/oracle/[PdbName]/]' ); --[更换为自己的实际相关参数],比如所对应的[PDB1],[admin],[dhjhjd3dh11] CREATE PLUGGABLE DATABASE PDB1 ADMIN USER admin IDENTIFIED BY dhjhjd3dh11 FILE_NAME_CONVERT=('/data/oracle/ORADB/pdbseed/', '/data/oracle/PDB1/' ); --查询可被克隆的PDB以及地址,也就是FILE_NAME_CONVERT的第一个参数 SELECT FILE#, NAME, CON_ID FROM V$DATAFILE; --或者 SELECT FILE#, NAME, CON_ID FROM V$DATAFILE WHERE CON_ID = 2; CON_ID ---------- 5 /data/oracle/ORADB/pdbseed/system01.dbf 2 6 /data/oracle/ORADB/pdbseed/sysaux01.dbf 2 8 /data/oracle/ORADB/pdbseed/undotbs01.dbf 2
复制

(二)表空间创建

1.查询需要创建的表空间

❗在这里需要查询一下源库中需要单独创建哪些表空间,避免导入时报错,另外需要规划好表空间大小。使用以下方式进行查询

-- 在源库上查询需要单独创建的表空间,“[OwnerName]替换成实际的owner” select distinct tablespace_name from dba_segments where owner = '[OwnerName]'; -- 源库查询表空间需要创建多大,查看已用表空间来进行分配表空间大小。“[OwnerName]替换成实际的owner”。 SELECT tablespace_name, SUM(bytes) / 1024 / 1024 / 1024 AS "总大小(GB)", SUM(bytes) / 1024 / 1024 / 1024 - SUM(free_space) / 1024 / 1024 / 1024 AS "已用大小(GB)", SUM(free_space) / 1024 / 1024 / 1024 AS "剩余大小(GB)" FROM ( SELECT tablespace_name, bytes, 0 AS free_space FROM dba_data_files UNION ALL SELECT tablespace_name, 0 AS bytes, bytes AS free_space FROM dba_free_space ) WHERE tablespace_name IN ( SELECT DISTINCT tablespace_name FROM dba_segments WHERE owner = '[OwnerName]' ) GROUP BY tablespace_name;
复制

2.创建表空间

❗需要切换到刚刚创建的pdb中执行。创建表空间有两种方式,分别为普通表空间,大文件表空间。

(1) 创建普通表空间

表空间初始大小为 30GB,文件会自动扩展,每次扩展 1GB。MAXSIZE 最大为100G

CREATE TABLESPACE [TABLESPACEName] DATAFILE '[/path/to/datafile1.dbf]' SIZE 30G AUTOEXTEND ON NEXT 1G MAXSIZE 100G;
复制
由于受最大块数(DB_BLOCK_SIZE)限制,无法创建较大文件,普通表空间到达一定大小左右就需要重新添加数据文件。
ALTER TABLESPACE [TABLESPACEName] ADD DATAFILE '[/path/to/datafile2.dbf]' SIZE 20G AUTOEXTEND ON NEXT 1G MAXSIZE 50G;
复制
(2)创建大文件表空间

创建一个大文件表空间(Bigfile Tablespace),表空间中只有一个数据文件文件初始大小为 100GB,每次扩展 1GB,无限制 (MAXSIZE UNLIMITED),适合支持大规模数据的系统,简化了数据文件的管理(仅需管理一个文件)。缺点是单一文件过大会集中 I/O 压力,可能影响性能。如果文件受损或需要迁移,可能会影响整个表空间,这种概率很低但是也得考虑

CREATE BIGFILE [TABLESPACE] example_bigfile DATAFILE '[/path/to/datafile.dbf]' SIZE 100G AUTOEXTEND ON NEXT 1024M MAXSIZE UNLIMITED;
复制

(3)比较和选择

属性 普通表空间 大文件表空间
数据文件数量 多个(最多 1022 个) 一个
单文件大小 通常受 DB_BLOCK_SIZE 限制(如 32GB) 最大可达 32TB 或更高(取决于配置)
管理复杂性 高(需要管理多个数据文件) 低(仅管理一个文件)
元数据开销 高(多个文件增加元数据)
I/O 性能 支持分布式 I/O,性能更高 I/O 集中,可能导致性能瓶颈
适用场景 中小型应用,数据增长相对稳定 超大规模系统,如数据仓库或云数据库

(三)创建账号

❗基于SCHEMAS模式数据泵只导出指定用户(模式)的对象,不会导出用户本身或角色信息。需手动创建用户。如果目标数据库中不存在该 Schema(用户),需要手动创建。在 PDB 环境下,确保导入前已创建对应的用户账号,否则需要手动处理。

-- 查询需要创建哪些账号,如果还有其他需要排除的在这里补充'[OTHERNAME]' SELECT username, created FROM DBA_USERS WHERE username NOT IN ( 'SYS', 'SYSTEM', 'DBSNMP', 'SYSMAN', 'MDSYS', 'OLAPSYS', 'ORDSYS', 'CTXSYS', 'XDB', 'OUTLN', 'WKSYS', 'DIP', 'EXFSYS', 'LBACSYS', 'APPQOSSYS', 'REMOTE_SCHEDULER_AGENT', 'OJVMSYS', 'GSMADMIN_INTERNAL', 'SYSBACKUP', 'SYSDG', 'SYSKM', 'AUDSYS', 'ANONYMOUS', 'SCOTT', 'XS$NULL', 'GGSYS', 'DVSYS', 'DVF', 'PDBADMIN', 'APPUSER','[OTHERNAME]' ) AND username NOT LIKE 'APEX%' -- 过滤 APEX 用户 AND username NOT LIKE 'FLOWS_%' -- 过滤 APEX 的旧版本用户 AND username NOT LIKE 'ORA%' -- 过滤 Oracle 预留的 ORA 开头用户 AND username NOT LIKE 'XS$%' -- 过滤系统特殊用户 AND ACCOUNT_STATUS = 'OPEN' -- 只查询启用的用户 ORDER BY created; -- 创建账号 CREATE USER [USERNAME] IDENTIFIED BY [Password]; GRANT CREATE SESSION TO [USERNAME]; GRANT [权限] TO [USERNAME];
复制

(四)创建导入目录以及授权导入账号权限

--切入到需要导入的pdb下 alter session set container=[PDBName]; --创建导入的目录 create directory dump_dir as '/data/input'; --授权导入账号的权限,我这里直接使用的system,也可根据需求改成相应其他账号 grant read,write on directory dump_dir to [system];
复制

(五)更改字符集

创建库设置了默认字符集,如果需要更改字符集,根据以下操作,下面介绍将UTF8更改为GBK。

❗需要注意的是不能使用下面方式将GBK转为UTF-8

--切换PDB alter session set container=[PDBName]; --启动pdb startup; --启用Oracle数据库的受限模式。在受限模式下,只有特定的用户(通常是管理员)可以连接到数据库,而其他用户则无法连接。 -- 这通常用于进行维护或紧急情况下的数据库访问控制。 ALTER SYSTEM ENABLE RESTRICTED SESSION; -- 更改字符集 ALTER DATABASE CHARACTER SET INTERNAL_USE ZHS16GBK; --查看字符集 select userenv('language') from dual; USERENV('LANGUAGE') -------------------------------------------------------------------------------- AMERICAN_AMERICA.ZHS16GBK --关闭受限模式 ALTER SYSTEM DISABLE RESTRICTED SESSION;
复制

二、导入步骤

(一)把需要恢复的文件传到 dump_dir并解压

❗需要注意dump_dir目录权限

--切换到dump_dir cd /data/input --解压 tar -zxvf dmpname_xxx.tar.gz dmpname_xxx.dmp dmpname_xxx.dmp.log --解压后有两个文件,一个说是数据泵文件,一个是导出时候的日志,导出后的日志可以看到导出的一些详细信息,如果后续需要对对象进行验证,可以参考日志中的内容,比如表的数据量,表大小之类
复制

(二)执行导入

--执行导入 nohup impdp system/[password]@10.153.x.x:1521/[PDBName] DUMPFILE=dmpname_xxx.dmp DIRECTORY=dump_dir logfile=xx_EXP.log SCHEMAS=[SCHEMASName] PARALLEL=8 >xx_nohup_"$(date +'%Y-%m-%d_%H-%M-%S').log"& --1. nohup允许命令在后台运行,即使用户注销终端后,任务也不会中断。 --2. impdp 数据泵导入工具,用于导入从 `expdp` 导出的数据文件。 --3. system/[password]@10.153.x.x:1521/[PDBName] --`system`: Oracle 的用户(在这里是 `SYSTEM` 用户)。 --`[password]`: `SYSTEM` 用户的密码。 --`10.153.x.x`: Oracle 数据库所在服务器的 IP 地址。 --`1521`: Oracle 数据库监听的端口号。 --`[PDBName]`: Oracle 数据库中的容器数据库(Pluggable Database)的名称。 --4. DUMPFILE=dmpname_xxx.dmp指定要导入的数据泵文件名称。 --5. DIRECTORY=dump_dir 指定数据泵文件所在的目录。这个目录名是一个 Oracle 数据库中创建的逻辑目录对象,对应服务器上的物理路径。 --6. logfile=xx_EXP.log指定导入操作的日志文件名称,日志记录导入过程中的信息、警告和错误。 --7. SCHEMAS=[SCHEMASName]指定要导入的数据库模式(Schema)。如果这里和导入的schema不一致需要修改为remap_schema=[源schema账号]:[导入环境的schema账号] --8. PARALLEL=8指定并行导入的工作进程数量(这里是 8 个)。 --9. >xx_nohup_"$(date +'%Y--%m--%d_%H--%M--%S').log" 将命令的标准输出重定向到文件xx_nohup_"$(date +'%Y--%m--%d_%H--%M--%S').log" --10. & 将整个导入任务放到后台运行,使用户可以继续使用终端。
复制

三、其他常见的问题

(一)卡在视图导入,进程夯住的解决方法。

❗oracle19c 存在bug Import Hangs During Import of Views in 19c (Doc ID 2676946.1),具有较高递归的复杂视图导入时会导致作业任务夯住

1.解决方法1

PSU/RU补丁打到最新,目前博主打的36582781是已经修复了这个问题

2.解决方法2

手动跳过卡主视图再次导入

-- 1、查看作业任务 sqlplus system/[password]@10.153.x.x:1521/[PDBName] col owner_name for a20 col job_name for a20 col state for a20 set linesize 1000 col operation for a20 col job_mode for a20 select * from dba_datapump_jobs; -- 2、根据活跃的作业任务查看impdp,看卡在哪个视图 impdp attach=SYS_IMPORT_SCHEMA_01 system/[password]@10.153.x.x:1521/[PDBName] --3、跳过视图 nohup impdp system/[password]@10.153.x.x:1521/[PDBName] DUMPFILE=dmpname_xxx.dmp DIRECTORY=dump_dir logfile=xx_view_dump_dir_EXP$(date +'%Y-%m-%d_%H-%M-%S').log SCHEMAS=[SCHEMASName] PARALLEL=8 exclude=sequence,table,index,comment,function,procedure,constraint,VIEW:\"IN \(\'[view1]\',\'[view2]\',\'[view3]\'\)\"> XX_VIEW_nohup_$(date +'%Y-%m-%d_%H-%M-%S').log 2>&1 & --4、如果卡的视图较多,这个需要多次重复操作 --卡在某个任务,可以先 impdp attach=SYS_IMPORT_SCHEMA_02 system/[password]@10.153.x.x:1521/[PDBName] stop_job=immediate --然后再加上需要通过的视图再导。比较麻烦
复制

(二)单独导入差别对象

--查看验证是否对应最新序列 SELECT sequence_owner, sequence_name, last_number, max_value, increment_by, cache_size FROM all_sequences WHERE sequence_owner = '[sequence_owner_NAME]'; --或 select count(*) FROM all_sequences WHERE sequence_owner = '[sequence_owner_NAME]'; --如果导入Oracle ORA-31684 错误,这表明序列未能被覆盖或替换。 --要解决这个问题手动删除序列,通过执行 DROP SEQUENCE 语句来删除现有的序列,然后再重新导入。例如: DROP SEQUENCE [sequence_owner_NAME].[sequenceName]; --如果序列上有依赖约束,可以使用 CASCADE CONSTRAINTS 选项来删除序列及其所有依赖关系: DROP SEQUENCE [sequence_owner_NAME].[sequenceName]CASCADE CONSTRAINTS; --或者也可以直接全部给删除了重新导入 SET SERVEROUTPUT ON DECLARE CURSOR c_sequences IS SELECT sequence_name FROM all_sequences WHERE sequence_owner = '[sequenceName]'; -- 修改为你的目标模式 v_sequence_name all_sequences.sequence_name%TYPE; BEGIN FOR rec IN c_sequences LOOP v_sequence_name := rec.sequence_name; EXECUTE IMMEDIATE 'DROP SEQUENCE ' || v_sequence_name; dbms_output.put_line('Sequence ' || v_sequence_name || ' dropped.'); END LOOP; END; / --导入 nohup impdp system/[password]@10.153.x.x:1521/[PDBName] DUMPFILE=dmpname_xxx.dmp DIRECTORY=dump_dir logfile=xx_sequence_dump_dir_EXP$(date +'%Y-%m-%d_%H-%M-%S').log SCHEMAS=[SCHEMASName] PARALLEL=8 INCLUDE=SEQUENCE TABLE_EXISTS_ACTION=REPLACE >XX_sequence_nohup_$(date +'%Y-%m-%d_%H-%M-%S').log 2>&1 &
复制

(三)查询导入的对象数

--视图 SELECT count(VIEW_NAME) FROM user_views; --表 SELECT count(*) FROM user_tables; --索引 SELECT count(*) FROM user_indexes;
复制

(四)删除索引单独索引

--删除当前用户的索引 BEGIN FOR idx IN ( SELECT index_name FROM user_indexes WHERE index_type != 'LOB' ) LOOP EXECUTE IMMEDIATE 'DROP INDEX ' || idx.index_name; END LOOP; END; / --重新导入 nohup impdp system/[password]@10.153.x.x:1521/[PDBName] DUMPFILE=dmpname_xxx.dmp DIRECTORY=dump_dir logfile=xx_INDEX_dump_dir_EXP$(date +'%Y-%m-%d_%H-%M-%S').log SCHEMAS=[SCHEMASName] PARALLEL=8 INCLUDE=INDEX TABLE_EXISTS_ACTION=REPLACE >XX_INDEX_nohup_$(date +'%Y-%m-%d_%H-%M-%S').log 2>&1 &
复制

(五)删除pdb重新再来(谨慎操作)

如果导入碰到了一些问题,需要重新再来,可以删除pdb了重新导入,但是谨慎使用,并且在已知风险情况下执行

--关闭pdb sqlplus / as sysdb alter session set container=[PDBName]; ALTER PLUGGABLE DATABASE [PDBName] CLOSE IMMEDIATE; exit --删除 sqlplus / as sysdb DROP PLUGGABLE DATABASE [PDBName] INCLUDING DATAFILES;
复制

(六) 导入报错无法扩展表空间“Resumable error: ORA-01691: by 8192 in tablespace USERS”

导入过程中报错无法扩展表空间,前面创建表空间已经提到过表空间由于受最大块数(DB_BLOCK_SIZE)限制,无法创建较大文件,普通表空间到达一定大小左右就需要重新添加数据文件。所以解决这个问题需要新添加一个表空间文件

--查看表空间使用 SELECT tablespace_name, SUM(bytes) / 1024 / 1024 / 1024 AS "总大小(GB)", SUM(bytes) / 1024 / 1024 / 1024 - SUM(free_space) / 1024 / 1024 / 1024 AS "已用大小(GB)", SUM(free_space) / 1024 / 1024 / 1024 AS "剩余大小(GB)" FROM ( SELECT tablespace_name, bytes, 0 AS free_space FROM dba_data_files UNION ALL SELECT tablespace_name, 0 AS bytes, bytes AS free_space FROM dba_free_space ) GROUP BY tablespace_name; --新添加数据文件扩容表空间 ALTER TABLESPACE [TABLESPACEName] ADD DATAFILE '[/path/to/datafile2.dbf]' SIZE 20G AUTOEXTEND ON NEXT 1G MAXSIZE 50G; --需要注意的是扩容的新文件文件名不能和之前一样,另外建议创建的路径和之前一致!!! --可以通过下面语句查询出之前的表空间路径 SELECT FILE_NAME, TABLESPACE_NAME FROM DBA_DATA_FILES WHERE TABLESPACE_NAME = '[TableName]';
复制
最后修改时间:2024-12-17 11:32:49
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论

vic
暂无图片
关注
暂无图片
获得了80次点赞
暂无图片
内容获得13次评论
暂无图片
获得了23次收藏
TA的专栏
ORACLE-日常运维
收录6篇内容
目录
  • 一、环境准备
    • (一)创建pdb
    • (二)表空间创建
      • 1.查询需要创建的表空间
      • 2.创建表空间
    • (三)创建账号
    • (四)创建导入目录以及授权导入账号权限
    • (五)更改字符集
  • 二、导入步骤
    • (一)把需要恢复的文件传到 dump_dir并解压
    • (二)执行导入
  • 三、其他常见的问题
    • (一)卡在视图导入,进程夯住的解决方法。
    • (二)单独导入差别对象
    • (三)查询导入的对象数
    • (四)删除索引单独索引
    • (五)删除pdb重新再来(谨慎操作)
    • (六) 导入报错无法扩展表空间“Resumable error: ORA-01691: by 8192 in tablespace USERS”