(一)问题背景

最近在生产环境中,开发人员误操作,使用truncate将oracle数据库某个表的数据全部删除了,在删除之后,开发人员发现自己闯祸了,于是联系值班的DBA进行紧急数据恢复。

经过分析,表被truncate后,使用一般的闪回表、闪回查询、闪回事物等方法,是不可能将数据找回来的,可以使用闪回数据库、闪回数据归档的方法来进行恢复,但是通常在生产环境中,都不会开启这2个特性,所以剩下的只有使用RMAN进行数据恢复了。

对于使用RMAN进行数据恢复,可以在生产环境上直接进行,也可以恢复到其它机器上。

  • 直接在生产环境上恢复:①需要停止生产数据库;②数据库需要保持一致性,比如说,我需要将数据库恢复到12:00,那么数据库中其他表的数据也将恢复到12点,有可能会丢失较多数据;③如果恢复过程中出现其它问题也比较麻烦,耽误了生产业务执行。
  • 恢复到其它机器上:②不需要停生产库;②仅仅丢失truncate表的数据,比如说,我需要将数据库恢复到12:00,那么我只需将整个库在测试环境上恢复到12点,再将我们丢失表的数据通过DB_LINK或数据泵等方式恢复到生产环境,生产环境其它表的数据是不受影响的;③恢复失败,并不会影响到生产库。

所以,经过一番考虑,决定将数据库恢复到其它机器上,然后再将truncate表的数据导回到生产环境。

此次恢复操作是同事做的,在恢复过程中,由于流程不熟悉,查资料耽误了一些时间(大约20分钟),虽然数据库恢复完成了,但没有达到快速恢复的要求。思考了一下,假如自己来做,能否在开发人员焦急等待的情况下,自己毫不慌乱、快速稳定的完成数据库恢复?确实是不可能的。一方面恢复流程不熟练,毕竟数据库恢复操作一年也不可能遇到几次,另一方面在用户及开发人员催促的情况下,DBA也很容易慌张,影响效率。因此最好的方式是:提前演练、写好操作流程。当故障发生时,照着文档操作,以最快的速度恢复生产。

(二)环境准备

  生产环境 异机环境
操作系统 RedHat6.7 RedHat6.7
数据库版本 11.2.0.4(RAC,2个节点) 11.2.0.4(单节点)
db_name prodb prodb
instance_name prodb1、prodb2 prodb
数据库安装情况 安装GI+数据库软件+创建数据库 安装GI+数据库软件 (不用创建数据库)
磁盘组信息 OCR   : 3*1GB,normal
DATA :3*5GB,external
ARCH :  1*5GB,external
OCR   : 3*1GB,normal
DATA :3*5GB,external
ARCH :  1*5GB,external

备注:为了方便,在后续环境中,生产环境数据库简称“生产库”,异机环境的数据库简称“测试库”。

(三)测试方案

(四)详细执行过程

(4.1)创建测试表

这里创建了2个测试表,作用分别如下:

lijiaman.test01:用于做truncate测试的表,最后在测试库需要进行test01表的恢复。

lijiaman.test02:用于模拟数据库事务,对该表不断执行插入操作,使得数据库产生大量归档日志。

(Ⅰ)表test01,一共有14笔数据。

SQL> CREATE TABLE test01 AS SELECT * FROM scott.emp;
Table created SQL> select count(*) from test01;
COUNT(*)
----------
14

(ⅠⅠ)表test02,持续往里面写入数据

--创建表test02
create table test02
(
col1 number,
col2 number,
col3 varchar2(30),
col4 date,
col5 varchar2(100)
); --创建随机数据插入存储过程
create or replace procedure p_insert_test02 is
BEGIN
FOR i IN 1..10000 LOOP
insert into test02(col1,col2,col3,col4,col5)
values
((select round(dbms_random.value(1, 100000000)) from dual),
(select round(dbms_random.value(10000, 100000000)) from dual),
(select dbms_random.string('a', 25) from dual),
sysdate,
(select dbms_random.string('a', 85) from dual));
commit;
END LOOP;
end p_insert_test02; --制定job,没隔30s执行一次上面的存储过程
declare
job1 number;
begin
sys.dbms_job.submit(job => job1,
what => 'p_insert_test02;',
next_date => sysdate,
interval => 'sysdate + 30/(1440*60)'); --每隔30s向test02表插入10000笔随机数据
commit;
end;
/

(4.2)对数据库进行完全备份

rman target /

RMAN> run {
allocate channel c1 type disk;
allocate channel c2 type disk;
sql' alter system archive log current';
backup database format '/databaseBackup/full_db_%U';
sql' alter system archive log current';
backup archivelog all format '/databaseBackup/archlog_%U';
backup current controlfile format '/databaseBackup/controlfile_%U';
backup spfile format '/databaseBackup/spfile_%U';
release channel c1;
release channel c2;
}

生成的备份集如下:

[oracle@node1 databaseBackup]$ ls -l
total 4136752
-rw-r----- 1 oracle asmadmin 1451128832  Sep 27 19:27 archlog_0iucr7hg_1_1
-rw-r----- 1 oracle asmadmin 1462116352  Sep 27 19:27 archlog_0jucr7hh_1_1
-rw-r----- 1 oracle asmadmin     1406464   Sep 27 19:27 archlog_0kucr7lr_1_1
-rw-r----- 1 oracle asmadmin   18841600   Sep 27 19:28 controlfile_0lucr7m2_1_1
-rw-r----- 1 oracle asmadmin  805953536   Sep 27 19:25 full_db_0eucr7f7_1_1
-rw-r----- 1 oracle asmadmin  477528064   Sep 27 19:25 full_db_0fucr7f7_1_1
-rw-r----- 1 oracle asmadmin   18841600   Sep 27 19:25 full_db_0gucr7h3_1_1
-rw-r----- 1 oracle asmadmin        98304   Sep 27 19:25 full_db_0hucr7ha_1_1
-rw-r----- 1 oracle asmadmin        98304   Sep 27 19:28 spfile_0mucr7m5_1_1

确认归档日志备份情况,可以看到,本次全备份归档日志备份到了thread1:57,thread2:48。

RMAN> list archivelog all;

List of Archived Log Copies for database with db_unique_name PRODB
=====================================================================

Key     Thrd  Seq     S  Low Time
------- ---- ------- - ---------
3            1    6       A 24-SEP-19
        Name: +ARCH/prodb/archivelog/2019_09_24/thread_1_seq_6.258.1019832847
......
100        1     57      A 27-SEP-19
        Name: +ARCH/prodb/archivelog/2019_09_27/thread_1_seq_57.355.1020108489

1           2     1       A 24-SEP-19
        Name: +ARCH/prodb/archivelog/2019_09_24/thread_2_seq_1.256.1019830885
......
80         2     48      A 24-SEP-19
        Name: +ARCH/prodb/archivelog/2019_09_24/thread_2_seq_48.335.1019838555

(4.3)数据库正常运行,产生大量归档

由于日志序列号是递增的(以resetlogs打开数据库例外),因此查询每个实例上生成的最大日志即可

SELECT *
FROM
(SELECT thread#,
SEQUENCE#,
NAME,
ROW_NUMBER() OVER(PARTITION BY thread# ORDER BY SEQUENCE# DESC) rn
FROM V$ARCHIVED_LOG)
WHERE rn=1;

结果为:

即thread1上的归档日志最大序列号为67,thread2上的归档日志最大序列号为48(这里因为个人电脑开较多虚拟机太卡,所以只开了节点1,节点2就没有日志生成,并不影响本次实验结果的准确性)。

(4.4)模拟test01表被truncate,记下时间

SQL> select sysdate from dual;

SYSDATE
-------------------
2019-09-27 19:37:31 SQL>
SQL> truncate table test01; Table truncated.

(4.5)数据库正常运行,产生大量归档

上一次备份到了sequence=57的日志,上一次备份后又生成了25个日志,这里生成大量日志是为了模拟生产数据库这次交易的情况。

(4.6)开发人员发现表数据被truncate

开发人员发现程序报错,查看表test01,发现数据全没了,开发人员确认数据被自己删除(假设)。

(4.7)DBA执行异机恢复

思路整理:

本次恢复,需要将test01表恢复到truncate之前,我们需要有执行truncate操作之前的数据库全备和归档备份。第一次全备归档日志文件之备份到了thread1=57,thread2=48,在执行全被之后,又生成了许多的日志文件,我们要将数据库恢复到truncate之前(这里以我们记录的时间2019-09-27 19:37:31 为恢复点),那么我们还需要新的日志来做恢复,需要的日志如下:

thread1:日志57~67肯定需要,日志67~82不一定需要;

thread2:由于节点未开启,不需要日志来做恢复。

step1:将生产库的备份集传到测试库

[oracle@node1 databaseBackup]$ scp * 192.168.10.66:/databaseBackup/

step2:对恢复需要的归档日志进行再次备份,得到缺少的归档日志

run {
allocate channel c1 type disk;
sql' alter system archive log current';
backup archivelog all format '/databaseBackup/archlog_20190927_%U';
release channel c1;
}

得到的归档日志备份集如下:

-rw-r----- 1 oracle asmadmin 1621476864 Sep 27 20:50 archlog_20190927_0nucrcd2_1_1
-rw-r----- 1 oracle asmadmin 1643560960 Sep 27 20:51 archlog_20190927_0oucrcg5_1_1
-rw-r----- 1 oracle asmadmin 1581030912 Sep 27 20:53 archlog_20190927_0pucrcjj_1_1

传送到备库上
[oracle@node1 databaseBackup]$ scp archlog_20190927_0* 192.168.10.66:/databaseBackup/
step3:根据生产库的pfile,构造一个测试库的pfile

[oracle@test dbs]$ pwd
/u01/app/oracle/product/11.2.0/db_1/dbs [oracle@test dbs]$ vim init initprodb.ora
# 添加如下信息
audit_file_dest='/u01/app/oracle/admin/prodb/adump'
audit_trail='db'
compatible='11.2.0.4.0'
control_files='+DATA/prodb/controlfile/current.260.1019830577'
db_block_size=8192
db_create_file_dest='+DATA'
db_domain=''
db_name='prodb'
diagnostic_dest='/u01/app/oracle'
dispatchers='(PROTOCOL=TCP) (SERVICE=prodbXDB)'
enable_ddl_logging=TRUE
log_archive_dest_1='LOCATION=+arch'
log_archive_format='%t_%s_%r.dbf'
open_cursors=300
pga_aggregate_target=399507456
processes=200
remote_login_passwordfile='exclusive'
sessions=225
sga_target=1199570944
prodb.undo_tablespace='UNDOTBS1' [oracle@test dbs]$ ls
hc_prodb.dat hc_testdb1.dat hc_testdb.dat init.ora initprodb.ora lkTESTDB

创建pfile里面涉及到的路径:

[oracle@test ~]$ mkdir -p /u01/app/oracle/admin/prodb/adump

step4:将备库启动到nomount状态

[oracle@test ~]$ export ORACLE_SID=prodb
[oracle@test ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Fri Sep 27 20:58:15 2019 Copyright (c) 1982, 2013, Oracle. All rights reserved. Connected to an idle instance. SQL> startup nomount;
ORACLE instance started. Total System Global Area 1202556928 bytes
Fixed Size 2252704 bytes
Variable Size 402653280 bytes
Database Buffers 788529152 bytes
Redo Buffers 9121792 bytes
SQL>

step5:将数据库添加到HA中,以便可以使用ASM存储

[oracle@test ~]$ srvctl add database -d prodb -o /u01/app/oracle/product/11.2.0/db_1

step6:恢复控制文件,修改pfile文件,重新启动数据库到mount状态

RMAN> restore controlfile from "/databaseBackup/controlfile_0lucr7m2_1_1";

注意:此时存在一个问题,我们在构造pfile文件的时候,里面填写了控制文件的位置,这个位置是生产库上的位置,我们执行控制文件恢复后,需要对参数文件中的control_files参数进行修改,修改方法如下:

--首先,确认contril file在asm中的位置,

ASMCMD> pwd
+data/prodb/controlfile
ASMCMD> ls -lt
Type Redund Striped Time Sys Name
CONTROLFILE UNPROT FINE SEP 27 21:00:00 Y current.256.1020114329

--接下来,修改pfile文件的control_files参数

[oracle@test ~]$ cd $ORACLE_HOME/dbs
[oracle@test dbs]$ vim initprodb.ora
# 改control_files位置
control_files='+data/prodb/controlfile/current.256.1020114329'

--重启数据库到mount状态

[oracle@test ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Fri Sep 27 21:17:26 2019

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options SQL> shutdown immediate
ORA-01507: database not mounted ORACLE instance shut down.
SQL> startup mount
ORACLE instance started. Total System Global Area 1202556928 bytes
Fixed Size 2252704 bytes
Variable Size 402653280 bytes
Database Buffers 788529152 bytes
Redo Buffers 9121792 bytes
Database mounted.
SQL>

step7:注册新的归档日志备份集到备库的控制文件中

RMAN> catalog backuppiece "/databaseBackup/archlog_20190927_0nucrcd2_1_1";
RMAN> catalog backuppiece "/databaseBackup/archlog_20190927_0oucrcg5_1_1";
RMAN> catalog backuppiece "/databaseBackup/archlog_20190927_0pucrcjj_1_1";

step8:恢复数据库到truncate之前

RMAN>SQL"ALTER SESSION SET NLS_LANGUAGE=''AMERICAN''";
RMAN>SQL"ALTER SESSION SET NLS_DATE_FORMAT=''YYYY-MM-DD HH24:MI:SS''";
RUN{
SET UNTIL TIME '2019-09-27 19:37:31';
RESTORE DATABASE;
RECOVER DATABASE;
}

step9:确认数据是已经否恢复回来

--先以只读方式打开数据库,如果有问题,还可以重新执行恢复
SQL> alter database open read only;
Database altered. --确认数据是否找回来
SQL> select count(*) from lijiaman.test01;
COUNT(*)
----------
14

step10:如果没问题,关闭数据库,以resetlogs方式打开

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down. SQL> startup mount
ORACLE instance started. Total System Global Area 1202556928 bytes
Fixed Size 2252704 bytes
Variable Size 402653280 bytes
Database Buffers 788529152 bytes
Redo Buffers 9121792 bytes
Database mounted. SQL> alter database open resetlogs; Database altered.

恢复完成。

(4.8)将恢复的数据导入到生产环境

可以使用expdp/impdp或者是dblink将数据从测试库导入到生产库中。

【完】

oracle异机恢复测试的更多相关文章

  1. rman恢复方案和oracle异机恢复

    这篇文章主要介绍了rman恢复方案和oracle异机恢复,需要的朋友可以参考下 注:①恢复的前提是已经做好备份②完全恢复数据库是数据库遇到故障,在恢复时候没有丢失任何已经提交事物数据的恢复不完全恢复数 ...

  2. ORACLE 异机恢复

    有时候需要将大的数据库发布到客户现场或转移机器时,不得不考虑在异机上恢复已经调整.测试好的库. dumpdp 全备的方法虽然易用,但在处理对象.索引.空间的时候异常的出错,比如:见有些公司,建表.索引 ...

  3. 使用NBU进行oracle异机恢复

    windows平台的异机恢复,目录不同 1.异机环境准备安装oracle介质安装nbu客户端在异机主机的host文件中添加nbu server主机和原主机信息 2.恢复spfile文件 C:\> ...

  4. Oracle异机恢复

    RMAN异机恢复注意事项:1.RMAN 异机恢复的时候,db_name必须相同. 如果说要想改成其他的实例名,可以在恢复成功后,用nid 命令修改. 实例名的信息会记录到控制文件里,所以如果在恢复的时 ...

  5. Oracle之使用rman进行异机恢复测试记录

    本次测试目的是从生产数据库导出rman备份然后在测试数据库恢复 1,拷贝备份至相应目录 2,进入rman rman target \ 3,关闭数据库 shutdown 4,以nomount模式启动数据 ...

  6. oracle异机恢复参考官方文档

    How to use Rman Duplicate on ASM/RAC/OMF/Single Instance (Doc ID 840647.1) How to perform Rman dupli ...

  7. oracle异机恢复 open resetlogs 报:ORA-00392

    参考文档:ALTER DATABASE OPEN RESETLOGS fails with ORA-00392 (Doc ID 1352133.1) 打开一个克隆数据库报以下错误: SQL> a ...

  8. Hyper-V安装Oracle Linux6_4 Oracle db 12c并使用rman做异机恢复

    本文记录在Windows Server 2012 R2上安装Oracle Enterprise Linux 6.4以及使用RMAN进行进行异机恢复的过程. Windows服务器增加Hyper-V功能 ...

  9. Oracle 单实例 迁移到 RAC 实例 -- 使用RMAN 异机恢复

    Oracle 官网有关单实例迁移到RAC的一个步骤说明: How to Convert 10g Single-Instance database to 10g RAC using Manual Con ...

随机推荐

  1. 企查查app 初步探索

    企查查app sign算法破解初步探索 之前有说过企查查的sign的解密,但这次是企查查app的sign算法破解,目前是初步进程. 已删除!!!! 上边一些变量已经找到了,其中就有时间戳,其余两个需要 ...

  2. 电话面试总结(问的很细).md

    String 和其他基本类型有什么区别 Tip 基本类型有几种 为什么要给String创建一个常量池而不给其他类创建常量池 常量池的定义是什么 垃圾回收机制是如何运行的 对新生代和老年代不同的处理机制 ...

  3. qt学习笔记(1):qt点击运行没有反应。

    因为公司的项目需要,今天开始重新学习已经忘干净了的QT, 说起qt之前在学校刚接触的时候就打心底里喜欢这个编辑器, 因为一直使用vs做项目,面对着黑洞洞的窗口总让人不舒服, 自从接触了qt感觉迎来了曙 ...

  4. LeetCode115不同的子序列

    题目说明在这里就不贴出来了,相信打开这篇文章的小伙伴们肯定都是在刷LeetCode的. 一开始我的想法是dfs+回溯,结果运行超时,一开始我就觉得可能会超时,结果不出所料[手动笑哭]. 后来我想了下d ...

  5. JavaScript Array 数组方法汇总

    JavaScript Array 数组方法汇总 1. arr.push() 从后面添加元素,返回值为添加完后的数组的长度 var arr = [1,2,3,4,5] console.log(arr.p ...

  6. xcode7中搭建python开发环境

    1. 双击打开Xcode 2. 点击File->New->New Project 3. 在左边的面板选择Other,右边选择External Build Sytem,点击Next 4. 输 ...

  7. 牛客练习赛22C Bitset

    牛客练习赛22C 一共有 n个数,第 i 个数是 xi  xi 可以取 [li , ri] 中任意的一个值. 设 ,求 S 种类数. 感觉二进制真是一个神奇的东西. #include <iost ...

  8. CF 13E Holes

    Holes 题意:现在有一排洞,每个洞有一个弹力,能弹到ai之后的洞,球会弹到这个排的外面,现在有2个操作,0 a b 将第a个洞的弹力设为b, 1 a 将球放入第a个洞,求输出进洞的次数 和 弹出这 ...

  9. CodeForces 1018B The hat

    The hat 题解: 定义d[i]为第i个数和他对面的差值. 然后我们可以发现d[i]和d[i+1]的差值只会有3种情况2, -2, 0. 并且可以知道 d[i] = - d[i+n/2] 所以如果 ...

  10. bzoj3032 七夕祭题解

    题面 TYVJ七夕祭和11区的夏祭的形式很像.矩形的祭典会场由N排M列共计N×M个摊点组成.虽然摊点种类繁多,不过cl只对其中的一部分摊点感兴趣,比如章鱼烧.苹果糖.棉花糖.射的屋--什么的.Vani ...