草庐IT

RMAN恢复表及表分区

左轮Lee 2023-03-28 原文

Oracle version:19.3.0.0.0

目录:
一、功能简介
二、适用场景
三、使用限制
四、恢复的前提条件
五、恢复示例
六、参考文档

一、功能简介

Oracle 11g版本中,对于误删的数据或者表,可以通过undo或者回收站闪回的方式恢复,但是不能通过以上两种方式恢复的数据,则需要通过RMAN还原整个备份或者某个表空间或者impdp还原表(只能保证数据恢复到expdp备份的时刻)的方式来恢复,都不能高效的还原。
Oracle 12.1.0.1 开始RMAN新增单独恢复表及表分区功能,可以不用恢复整个数据库或者整个表空间来达到恢复表的目的,且能让数据恢复到误删的那一刻前。
Oracle 12.2.0.1 版本中RMAN又增强了两个方面:1.恢复前RMAN 会检查目标主机上是否有足够的空间来创建辅助实例。2.还可以将表和表分区恢复到新的schema中。

二、适用场景
  1. 恢复非常少量的表。这种情况下,TSPITR 不是最有效的解决方案,因为它将表空间中的所有对象全部恢复。
  2. 恢复逻辑上已损坏或已删除且从回收站清空的表。
  3. 恢复不能通过undo闪回的表(undo已过期被覆盖)。
  4. 恢复在 DDL 操作修改表结构后丢失的数据。
三、使用限制
  1. SYS用户下的表或者表分区不能被恢复。
  2. SYSTEM 和SYSAUX表空间下的表或者表分区不能被恢复。
  3. 备库上的表或者表分区不能被恢复。
  4. 使用了REMAP参数后不能恢复有NOT NULL约束的表。
四、恢复的前提条件
  1. 数据库必须处于读写模式。
  2. 数据库必须处于归档模式。
  3. 你必须有包含你想要恢复表或分区的时间点的RMAN备份。
  4. 恢复单个表分区时,目标数据库的COMPATIBLE初始化参数必须设置为11.1.0或以上。
五、恢复示例
  1. 准备数据
## 建表并写入数据
CREATE TABLE LZH_USER.TEST_RMAN ( ID NUMBER , NAME VARCHAR(100), dtime DATE) ;
INSERT INTO LZH_USER.TEST_RMAN SELECT LEVEL , 'mark-'||LEVEL ,SYSDATE FROM dual CONNECT BY LEVEL < 10 ; 
COMMIT ;
  1. 执行RMAN备份
run {
allocate channel CH1 type disk;
allocate channel CH2 type disk;
backup tag t_SPFILE spfile  format '/u01/app/dbbackup/%d_%T_%s_%p_SPFILE';
backup AS COMPRESSED BACKUPSET full database tag t_FULL format '/u01/app/dbbackup/%d_%T_%s_%p_FULL' ;
sql 'alter system archive log current';
backup tag t_ARCHIVE AS COMPRESSED BACKUPSET archivelog all format '/u01/app/dbbackup/%d_%T_%s_%p_ARCHIVE' ;
backup tag t_CONTROL current controlfile format '/u01/app/dbbackup/%d_%T_%s_%p_CONTROL';
release channel CH1;
release channel CH2;
}
  1. 继续插入数据
INSERT INTO LZH_USER.TEST_RMAN  VALUES (10, 'after rman backup',SYSDATE) ; 
COMMIT ;

SELECT a.* FROM LZH_USER.TEST_RMAN a ;
ID NAME                DTIME
-- ---------------------------------------
 1 mark-1              2022-07-25 13:35:38
 2 mark-2              2022-07-25 13:35:38
 3 mark-3              2022-07-25 13:35:38
 4 mark-4              2022-07-25 13:35:38
 5 mark-5              2022-07-25 13:35:38
 6 mark-6              2022-07-25 13:35:38
 7 mark-7              2022-07-25 13:35:38
 8 mark-8              2022-07-25 13:35:38
 9 mark-9              2022-07-25 13:35:38
10 after rman backup   2022-07-25 13:49:56
  1. 等待一会后(2022-07-25 13:50:15)删除表 LZH_USER.TEST_RMAN(同时从回收站删除)
drop table LZH_USER.TEST_RMAN purge ;
  1. 恢复表到数据删除前(2022-07-25 13:50:13)
    先创建好下面用到的文件夹
[root@localhost ~]# su - oracle
[oracle@localhost ~]$ mkdir /tmp/oracle/recover -p
[oracle@localhost ~]$ mkdir /tmp/recover/dumpfiles -p
  • 情形一:恢复到expdp文件,后续自行导入数据库中
RECOVER TABLE LZH_USER.TEST_RMAN
    UNTIL TIME "to_date('2022-07-25 13:50:13','yyyy-mm-dd hh24:mi:ss')"
    AUXILIARY DESTINATION '/tmp/oracle/recover'
    DATAPUMP DESTINATION '/tmp/recover/dumpfiles'
    DUMP FILE 'TEST_RMAN.dat'
    NOTABLEIMPORT;
  • 情形二:恢复到目标数据库的新表 TEST_RMAN_REC 中
RECOVER TABLE LZH_USER.TEST_RMAN
    UNTIL TIME "to_date('2022-07-25 13:50:13','yyyy-mm-dd hh24:mi:ss')"
    AUXILIARY DESTINATION '/tmp/oracle/recover'
    REMAP TABLE LZH_USER.TEST_RMAN:TEST_RMAN_REC;

SELECT * FROM LZH_USER.TEST_RMAN_REC ;
ID NAME                DTIME
-- ---------------------------------------
 1 mark-1              2022-07-25 13:35:38
 2 mark-2              2022-07-25 13:35:38
 3 mark-3              2022-07-25 13:35:38
 4 mark-4              2022-07-25 13:35:38
 5 mark-5              2022-07-25 13:35:38
 6 mark-6              2022-07-25 13:35:38
 7 mark-7              2022-07-25 13:35:38
 8 mark-8              2022-07-25 13:35:38
 9 mark-9              2022-07-25 13:35:38
10 after rman backup   2022-07-25 13:49:56

有个细节需要注意,如果REMAP是按官方文档这么写的:
REMAP TABLE 'LZH_USER'.'TEST_RMAN':'TEST_RMAN_REC';
则查询表的时候表上需要加 "" 号,即:SELECT * FROM LZH_USER."TEST_RMAN_REC" ;

另外,还可以通过指定SCN和日志号来恢复,这里就不做演示了。

  1. 恢复分区表,可参考下面的命令
    将表LZH_USER.TEST_RMAN_PARTITION的两个分区PATITION1和PATITION2恢复到新表PATITION1_REC和PATITION2_REC中,同时映射到新的表空间。
RECOVER TABLE LZH_USER.TEST_RMAN_PARTITION:PATITION1,LZH_USER.TEST_RMAN_PARTITION:PATITION12
    UNTIL TIME "to_date('2022-07-25 13:50:13','yyyy-mm-dd hh24:mi:ss')"
    AUXILIARY DESTINATION '/tmp/oracle/recover'
    REMAP TABLE 'LZH_USER'.'TEST_RMAN_PARTITION':'PATITION1':'PATITION1_REC',
                'LZH_USER'.'TEST_RMAN_PARTITION':'PATITION2':'PATITION2_REC',
    REMAP TABLESPACE 'USER_TS':'USER_TS_REC';
  1. 恢复pdb中的表,可以参考下面的命令
RECOVER TABLE LZH_USER.TEST_RMAN OF PLUGGABLE DATABASE TEST_PDB
    UNTIL TIME "to_date('2022-07-25 13:50:13','yyyy-mm-dd hh24:mi:ss')"
    AUXILIARY DESTINATION '/tmp/oracle/recover'
    REMAP TABLE 'LZH_USER'.'TEST_RMAN':'TEST_RMAN_REC';
  1. 恢复到新的schema中(从 LZH_USER --> LZH_USER_REC)(12.2.0.1增强功能),恢复到的时间点 2022-07-25 13:50:13 ,此刻 LZH_USER_REC 必须存在!不能新建一个schema,然后往里面恢复,会报用户不存在。
RECOVER TABLE LZH_USER.TEST_RMAN
    UNTIL TIME "to_date('2022-07-25 13:50:13','yyyy-mm-dd hh24:mi:ss')"
    AUXILIARY DESTINATION '/tmp/oracle/recover'
    REMAP TABLE LZH_USER.TEST_RMAN:LZH_USER_REC.TEST_RMAN_REC;
六、参考文档

Oracle 12.1.0.1 官方文档:
https://docs.oracle.com/database/121/BRADV/rcmresind.htm#BRADV686

Oracle 12.2.0.1 官方文档:
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/bradv/rman-recovering-tables-partitions.html#GUID-87B7F772-335F-4179-81C9-91678D026D01

有关RMAN恢复表及表分区的更多相关文章

  1. Ruby rpartition 与分区? - 2

    rpartition和partition有什么区别?我已经阅读了文档,但我认为它们是一样的。只是那些出现在后来的ruby​​版本中吗? 最佳答案 以下示例将有助于识别差异:"abccba".partition("b")#=>["a","b","ccba"]"abccba".rpartition("b")#=>["abcc","b","a"]所以区别在于rpartition搜索最右边的匹配项,而不是最左边的匹配项。 关于Rubyrpartition与分区?,我们在StackOverflow

  2. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

    文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

  3. python - 用于从 Python 到 Ruby 查找集合的所有分区的翻译函数 - 2

    我有以下python函数来递归查找集合的所有分区:defpartitions(set_):ifnotset_:yield[]returnforiinxrange(2**len(set_)/2):parts=[set(),set()]foriteminset_:parts[i&1].add(item)i>>=1forbinpartitions(parts[1]):yield[parts[0]]+bforpinpartitions(["a","b","c","d"]):print(p)有人可以帮我把它翻译成ruby​​吗?这是我目前所拥有的:defpartitions(set)ifnots

  4. ruby - 在 ruby​​ 中使用索引分区数组 - 2

    我正在寻找一种通过在ruby​​中使用索引来对数组进行分区的优雅方法例如:["a","b",3,"c",5].partition_with_index(2)=>[["a","b",3],["c",5]]到目前为止,我能想到的最好的方法是使用下面的["a","b",3,"c",5].partition.each_with_index{|val,index|index[["a","b",3],["c",5]]还有其他优雅的方法可以实现吗?谢谢! 最佳答案 你可以这样做:["a","b",3,"c",5].partition.with_i

  5. ruby - 警告 : RubyGems 1. 找不到 2+ 索引:RubyGems 将恢复到降低性能的旧索引 - 2

    警告:找不到RubyGems1.2+索引:RubyGems将恢复到降低性能的遗留索引。如果有人能帮我解决这个问题,我会给他们50.00美元我用尽了谷歌,重新安装了所有东西。我只想做gem安装...就是这样 最佳答案 删除罪魁祸首URL。就我而言,我使用的是Centos5.4,我收到的完整错误消息是:root#geminstallrackWARNING:RubyGems1.2+indexnotfoundfor:http://rubyworks.rubyforge.org/redhat/5/GEMS/x86_64/RubyGemswil

  6. ruby - 检查点并恢复 Ruby 中的堆 - 2

    Ruby的callcc捕获当前的延续,随后可以调用它来恢复控制,但不能恢复数据。我想捕捉当前的延续以及内存的当前图像。在我看来,捕获堆应该不是很困难;我可以依赖ObjectSpace::each_object和ObjectSpace::dump_all,或Marshal.dump,或简单地Object.clone。但是,我没有看到任何直接的方法来恢复堆。理想情况下,我想遍历object_id->object映射,为每个object_id恢复对象的旧图像(并重新添加object_id如果相应的对象已经被GC'd)。不出所料,没有Ruby级别的API可以让我这样做。我想知道是否有任何我可以

  7. ruby - 计算具有特定子集大小的集合分区 - 2

    给定一个包含n个元素的集合,我需要找到该集合的所有分区,其中有k个大小几乎相等的子集。例如,对于一个有7个元素和3个子集的集合,我只想要分区,其中有两个子集,每个子​​集有2个元素,一个子集有3个元素。我不想要一个包含1、2和4个元素的子集的分区。换句话说,有877possiblepartitions对于一组7个元素,但我只对由2/2/3个元素组成的子集组成的105个(?)分区感兴趣:实际上n大约是35,这意味着大约有2.81*1027个分区,“仅”8,338,573,669,964,101partitionswiththreesubsets.因此,我不可能将它们全部计算出来并费力地找

  8. ruby - 无法从 `sudo bundle install` 恢复 - 2

    我错误地在我的项目上运行了sudobundleinstall,现在当我以自己的身份运行它时bundleinstall我得到了权限被拒绝的错误(如下)。我在这里尝试了说明https://github.com/bundler/bundler/blob/master/ISSUES.md#other-problems,还尝试将我的项目克隆到一个新目录并从那里运行bundle,但没有用。请帮忙!error:cannotopen.git/FETCH_HEAD:PermissiondeniedRetryinggitfetch--force--quiet--tags"/home/akonsu/.bun

  9. arrays - 如何根据相邻元素的条件将数组拆分为有限数量的分区 - 2

    假设我有一组数字,例如ary=[1,3,6,7,10,9,11,13,7,24]我想在较小数字跟随较大数字的第一个点之间拆分数组。我的输出应该是:[[1,3,6,7,10],[9,11,13,7,24]]我已经尝试了slice_when,结果非常接近:ary.slice_when{|i,j|i>j}.to_a#=>[[1,3,6,7,10],[9,11,13],[7,24]]但它也在13和7之间拆分,所以我必须加入剩余的数组:first,*rest=ary.slice_when{|i,j|i>j}.to_a[first,rest.flatten(1)]#=>[[1,3,6,7,10],

  10. ruby-on-rails - 如何恢复/撤消对 Activerecord 对象的本地更改? - 2

    有没有办法撤消/恢复对Activerecord对象的任何本地更改。例如:user=User.firstuser.name#"Fred"user.name="Sam"user.name_was#"Fred"user.revertuser.name#"Fred"我知道我可以执行user.reload但我不必访问数据库来执行此操作,因为旧值存储在对象的状态中。最好是Rails3解决方案。 最佳答案 如thisanswer中所述Rails4.2在ActiveModel::Dirty中引入了restore_attributes方法:user=

随机推荐