备份恢复

备份

物理备份:对数据文件、控制文件、归档日志文件的备份

逻辑备份:对数据库内部逻辑对象的备份(exp、expdp)

恢复

数据库数据损坏的情况下,使用备份将受损的数据恢复回来的过程。

备份是一切数据安全手段的底线

物理备份

数据库里发生的所有事务都记录在联机重做日志文件中,联机重做日志文件是循环覆盖使用。联机重做日志文件主要的作用是实例崩溃恢复

Oracle有两种运行模式

归档模式

非归档模式

归档模式就是将所有的联机重做日志文件在循环覆盖以前进行归档,保留一份副本,非归档是默认的运行模式

归档模式决定了备份模式

冷备份

如果数据库是非归档模式,那么只能使用冷备份

数据库正常关闭,使用操作系统复制命令,备份所有的控制文件、数据文件

数据库正常关闭,会触发完全检查点信息,所有脏内存块都写入到了数据文件中,联机重做日志文件没有什么意义

要备份所有的数据文件、控制文件,不需要联机重做日志文件

如果使用的是abort关闭数据库,或者实例崩溃关闭,需要备份联机重做日志文件

关键是要获取所有的数据文件和控制文件的位置

clip_image001

热备份

数据库需要处于归档模式

数据库打开的状态下,可以进行表空间、数据文件的备份

归档对数据库的性能还是有一定影响的

归档可以不丢失任何数据

归档模式

clip_image002

归档模式中,对联机日志文件的归档分为两种模式:手工方式和自动归档

联机日志文件A写满以后,切换到B,手工归档模式需要手工的发出命令才能归档,如果不发出命令,A不会被归档,同时A也不能被覆盖,这样切换回来需要覆盖A的时候,整个数据库被挂起

除非测试,不要将生产数据库设置在手工归档模式

alter system archive log current;

自动归档模式中,当LGWR在将重做日志写入当前联机重做日志文件中,发现写满时,于是切换到另一个新的联机重做日志文件,进行日志切换,同时触发归档进程(ARCn),将当前已经写满的联机日志文件进行归档

其中的n表示我们启动了多个归档进程,Oracle 10g中n从1到30

clip_image003

归档文件的存放位置

clip_image004

自定义归档目录(注意,如果是存放在本地磁盘,一定加上location这个参数)

clip_image005

归档的一些参数

clip_image006

只有在将联机日志成功归档到这个目录以后,该日志文件才能够被覆盖。Reopen表示一旦不能够成功到目的地,则每隔一段时间(默认300秒)尝试一次,上面的语句设置时间间隔是600秒。

归档出现问题以后,最好的解决办法就是抓紧时间将归档目的地修复好。

另外一种解决方式就是将这个归档目录设置为defer。问题马上解决。但是要注意不能少于下面这个参数

clip_image007

所有归档目录都被误删除以后怎么办?

使用defer的办法是没有用的。只能恢复目录了。因为总是需要归档到一个地方去。

解决思路

1、首先将min_suceed设置成1

2、重新建立一个归档目录

3、将以前所有的归档目录设置成为defer

生成的归档日志文件的文件名?

clip_image008

默认为%t_%s_%r.dbf

%s:日志序列号

%S:固定长度的日志序列号,不足位在左边补0

%t:日志线程号

%T:固定长度的日志线程号,不足位在左边补0

%a:激活ID

%d:数据库名

%r:resetlogs生成的ID

热备份数据库

clip_image009

可以备份某个表空间所有的数据文件,也可以备份某个表空间下的某个数据文件,整个的备份过程中,表空间是可用的

将日志进行归档,然后备份到另外一个介质上。

恢复的时候,备份的数据文件要能够使用,至少要求在begin backup和end backup之间所有的归档日志,否则备份的介质没有任何意义。

对每一个表空间,都重复下面的操作。

1、开始备份

2、备份文件

3、结束备份

4、归档日志、备份归档日志

clip_image010

热备份原理

1、Oracle的数据块大小是操作系统块大小的整数倍,直接复制数据文件到备份介质的过程中,由于数据库一直可用,数据块中不断地有数据进进出出,使用操作系统命令复制数据文件时,是基于操作系统块进行复制的,也就是说复制一个操作系统块的时候,首先锁定这个块,复制完成以后,解锁这个块,这样这个块在复制前和复制后是一致的。但是对于一个Oracle数据库来说,一个块要分成几次进行复制,可能在复制一个操作系统数据块的时候,另外一个操作系统数据块被改变了,导致Oracle数据块在复制到备份介质以后,前一半是没有改动过的,后一半是改动过的,数据块的状态就不一致,数据块就能够使用,备份也就不能够使用,这叫做分离数据块现象(split blocks)

2、Oracle在数据块的头部和尾部各存了一个版本号,通过这个来确认这个数据块是否是分离数据块,Oracle修改过一个数据块以后,将这个数据块的版本号在头部和尾部各存放了一份

3、为了修复分离数据块现象,我们在备份某个表空间的时候,首先进行begin backup,通知数据库开始备份,在没有end backup命令之前,只要是进程修改了被备份的表空间所包含的数据块中的某条记录,Oracle就会把该数据块中所包含的所有的数据行的数据生成重做记录,记录到日志文件中

4、通过发出begin backup以后,第一次修改数据块中的数据行之前,在联机重做日志文件中记录数据块的修改前的数据,这样在热备份恢复的时候,一旦发现某个数据块被分离,则会利用日志文件里的记录的数据对整个数据块进行恢复

5、备份表空间中的所有的被修改过的数据块的所有数据行都被保存在了联机重做日志文件中,而不是只记录被修改的数据行的记录,因此在热备份过程中,会发现生成的联机重做日志文件的量比较大,这取决于业务的繁忙程度,例如DML量比较大,那么产生的日志会非常的多

6、发出begin backup命令以后,Oracle会对被备份的表空间所对应的数据文件触发文件级别的检查点进程,将内存中属于该表空间的所有脏数据块写入数据文件,检查点结束以后,数据文件头部(第一个和第一个数据块)的检查点SCN和日志序列号都不在变化,直至发出end backup,数据文件头部的SCN和日志序列号才被更新

7、在热备份的过程中,数据文件头部的SCN和日志序列号被冻结,但是数据文件本身还是最新的,和正常一样的更新和使用,DML更新了某个表,这些更新都会被写入到数据文件中去

8、冻结数据文件头部的SCN号和日志序列号,是为了将来使用热备份进行恢复的时候,能够知道应该从哪里开始应用重做记录,也就是备份的数据文件头部所记录的SCN和日志序列号,定位到日志文件中,从日志文件中找到开始的SCN,向后应用所有的日志文件

9、end backup以后,所有的数据文件的头部SCN和日志序列号推进到最新,因为数据文件本身就是最新的

clip_image011

模拟了一次在热备份过程中忽然断电的灾难恢复。系统提示一个数据文件损坏,我们怀疑可能是这个数据文件正在备份过程中实例崩溃,停止备份后,轻松解决。

clip_image012

另一种方式,使用介质恢复的模式也可以使数据库回退到原有的SCN点。

备份控制文件

只要在数据库结构发生变化以后,例如增加、删除、重命名数据文件或日志文件以后,都应该备份控制文件。

两种方式备份控制文件

1、二进制备份

2、SQL命令方式

clip_image013

备份到了这个文件中,里面是控制文件的重建语句。

clip_image014

介质恢复

还原restore

使用备份的文件替换损坏或丢失的文件,该阶段使用操作系统命令完成

恢复recovery

将归档的日志文件以及联机重做日志文件里的重做记录应用到还原出来的文件上,该阶段在SQLPLUS的recover命令完成

打开数据库的时候,数据文件、控制文件、联机重做日志文件必须同步,如果不同步,需要进行恢复,恢复成功以后才能打开数据库

系统检查点SCN

一致性是基于检查点SCN和日志序列号而言

控制文件里记录了三种重要的检查点SCN号

当检查点进程启动时,会将检查点结束时间的SCN号记录在控制文件中(SCN是一个以时间为参数的函数值),该检查点是全局范围内的,当发生文件级别的检查点(比如将某个表空间设置为begin backup而引起的检查点)时,则不会更新该系统检查点SCN

clip_image015

数据文件检查点SCN

当检查点进程启动时,包括全局范围的(例如发生日志切换)以及文件级别的(将表空间设置为只读、begin backup、或将某个数据文件设置为offline)检查点,这时会在控制文件里面记录每个数据文件上所发生的检查点SCN

(将数据文件设置为正常离线、只读时,将表空间设置为begin backup时,触发文件级别的检查点,并将该检查点更新控制文件和数据文件头部以后,就不再变化)

这个文件的检查点明显的高于其余文件,因为我们刚才执行一个begin backup命令,触发了一个文件检查点。

clip_image016

结束SCN

每个数据文件都会有一个结束SCN,在数据库正常运行期间,只要是在线的、可读写的数据文件,其终止SCN都为空

正常关闭数据库时,或者将数据文件正常离线、或只读时,都会由于触发了检查点进程,从而在控制文件里记录每个数据文件上的结束时的SCN号

clip_image017

Begin backup不能设置数据文件的结束SCN

clip_image018

通过设置数据文件的只读可以让结束SCN记录到数据文件中。

clip_image019

正常关闭数据库,每个数据文件的结束SCN都是一致的(只读、离线的除外)

clip_image020

数据库启动以后,数据文件的结束SCN都变成空。

在每个数据文件的头部,也记录了检查点SCN,该检查点SCN与控制文件中记录的数据文件的检查点SCN是一致的。也就是说,全局范围和数据文件级别的检查点,不仅会将检查点SCN记录在控制文件中,还会记录在数据文件的头部。

clip_image021

数据库正常关闭时,会触发一个完全检查点,并用该检查点结束时的SCN号更新以上4个检查点SCN(除了离线和只读的),下次数据库启动的时候,会比较这四个检查点SCN,如果他们相同,说明数据库是一致的,可以正常打开

如果数据库非正常关闭,例如掉电

导致数据库没有进行完全检查点就关掉了,每个在线、读写的数据文件的终止SCN仍然为空,下次数据库启动的时候,发现在线和读写的数据文件的终止SCN为空,则SMON进程会进行实例恢复

如果备份的数据文件覆盖当前的数据文件,则数据库会发现记录在控制文件里面的数据文件的检查点SCN号与从备份中还原的数据文件的头部记录的检查点SCN不一致,控制文件中的SCN比较新,备份中还原的数据文件头部的SCN比较旧,控制文件的SCN大于数据文件头部的SCN,数据库不能打开,要求对还原的数据文件进行恢复,应用重做记录,从而将该数据文件头部的SCN提升到控制文件里记录的SCN号

如果我们将备份的控制文件覆盖当前的控制文件,这时控制文件比较旧,而数据文件则是当前最新的数据文件,因此数据库会发现控制文件里面的SCN小于数据文件头部记录的SCN,于是进行恢复

启动数据库的时候,如果发现控制文件里记录的数据文件检查点SCN与数据文件头部记录的SCN相同,但是在每个在线的以及可读写的数据文件之间,他们的检查点SCN不同,那么会要求进行介质恢复,例如begin backup后,实例崩溃,重启数据库时就会发生这种情况,必须发出end backup命令才能打开数据库。

完全恢复

将数据库恢复到最新状态

非归档模式

归档模式

非归档模式下面的完全恢复

1、在非归档模式下面,如果出现介质的损坏,则必须使用一个在关闭状态下面所做的备份进行恢复

2、即使只丢失了一个数据文件,也必须还原所有的数据文件

3、关闭数据库,还原所有的控制文件、数据文件,如果备份了联机重做,也可以还原,不还原联机重做日志文件也是可以的

4、所用的备份,必须是在同一个时间点上做的备份

非归档模式的还原分为两种情况

1、备份时,同时备份了联机重做日志文件

关闭数据库,使用最近的备份,通过操作系统命令进行复制,将数据文件、控制文件、联机重做日志文件复制到这些文件所在的目录

2、备份时,没有备份联机重做日志文件

关闭数据库

从最近的备份中,还原所有的数据文件和控制文件

启动数据库,会报告找不到联机重做日志文件或者联机重做日志文件不匹配的错误消息

recover database until cancel using backup controlfile;

提示输入日志信息时,输入cancel

alter database open resetlogs;

最大的问题,丢失自上次备份以来所有的数据

归档模式下的完全恢复

在归档模式下面,如果控制文件和联机重做日志文件都没有损坏,而只是数据文件损坏,并且只要存在备份以及自从该备份以来所有的归档日志文件,就能够把数据库完全恢复到发生介质损坏的那个时间点上,通过recover命令实现恢复操作

如果所有控制文件损坏,或者整个联机重做日志文件丢失,或者自从上次备份以来丢失了某个归档日志文件,则需要进行不完全恢复

因此对于控制文件、联机重做日志文件、归档日志文件,一定要注意保存好

归档模式下面的完全恢复分为三个阶段

数据库级别

数据文件级别

表空间级别

如果恢复整个数据库,则需要将数据库启动到mount状态

如果恢复某个数据文件或者恢复某个表空间,则可以在数据库打开状态下进行

当发出recover命令时,Oracle会从所有被还原的数据文件头中选择一个最小的检查点SCN号以及日志序列号,从该日志序列号所指定的日志文件开始,向后依次开始应用所有的重做记录,直到每个数据文件头部的检查点SCN达到控制文件中所记录的数据文件检查点SCN为止,所有日志文件的序列号必须连贯,不能中断。

在恢复数据文件的时候,必须以独占的方式锁定被恢复的数据文件

数据文件联机或者正在被恢复,都不能进行恢复

好处

1、只需要恢复受损的数据文件

2、如果不是system或者undo表空间损坏,那么可以在数据库打开的情况下进行恢复

两个重要的视图

v$recover_file:哪些数据文件需要恢复

v$recovery_log:为了完全恢复受损的数据文件,需要哪些日志文件

三种恢复方式

1、recover database,关闭数据库使用

如果系统表空间或者undo表空间

所有数据文件损坏

2、recover tablespace <表空间的名称或者表空间编号>

非系统表空间、undo表空间损坏时建议使用这种方式

需要首先将受损的表空间离线

3、recover datafile <数据文件名称或者数据文件编号>

同上面的命令

都是在数据库打开和关闭的时候使用

在恢复数据的过程中,会使用到数据文件、控制文件、联机重做日志文件、归档日志文件

前三者都是联机的,后者是脱机的,因此在应用到归档日志文件的时候,数据库往往会提示输入归档日志的目录,一般来说,我们可能将归档日志备份到另外一个位置,然后删除当前位置的归档日志,但是通常不去改变他的名字。

如果我们将要恢复的归档日志放在了一个不同的位置,我们在恢复的时候,可以手工的指定位置,也可以通过设置下面的参数,让系统在我们指定的目录里面自动寻找

因为归档日志很多,我们在应用的时候,不希望都去指定,希望将归档日志都放在一个目录里面,通过指定参数,让Oracle在恢复的时候,自动的去寻找归档日志,自动的去应用。

数据库进行恢复,自动寻找归档日志的方法有三种

前提:将需要的归档日志集中存放在一个目录里面,然后设置了正确的dest路径

1、set autorecovery on

2、恢复时提示我们输入日志文件的路径,输入auto即可,Oracle会自动搜索日志文件进行应用

3、sql&gt;recover automatic datafile 4,直接自动进行恢复

完全恢复的四种方法

1、数据库打开状态,系统表空间和undo表空间未损坏,其他表空间损坏

注意:冷备份的时候,尽量把联机重做日志也备份上,否则恢复起来很麻烦

2、数据库处于关闭状态,系统表空间和undo表空间损坏。

注意:恢复undo表空间不能在数据库打开状态下进行。

3、数据库在打开的情况下,system表空间崩溃。

4、数据库关闭,非system和undo表空间损坏

只要是控制文件、联机重做日志文件没有损坏、归档日志全,数据文件有备份,恢复就非常的简单。不管你是什么故障。

1

clip_image022

2

clip_image023

3

clip_image024

4

clip_image025

不完全恢复的场合

1、进行完全恢复的时候,在应用归档日志的过程中,丢失了其中一个或者多个归档日志文件,因此我们只能将数据库不完全恢复到丢失的最早的那个归档日志文件为止

2、丢失了整个联机重做日志文件组,而该联机重做日志文件还没有完成归档

3、用户误删除了表里的数据,或误删除了表,或误删除了某个重要的用户,要恢复被误删除的数据,可以通过不完全恢复,将数据库恢复到误操作之前的时间点

4、当前控制文件全部丢失,并使用了备份的控制文件进行恢复,这时进行的不完全恢复,但是只要所有的归档日志、联机重做日志文件都在,仍然能够恢复所有的数据

不完全恢复有下面的两个前提

1、具有所有数据文件的备份,并且该备份是在要恢复到的时间点之前做的,例如要恢复到11:00点,那么备份就需要是11:00之前做的

2、具有从备份完成的时间点开始,到要恢复的时间点之间的所有归档文件

三种类型的不完全恢复

1、基于时间点的不完全恢复(time-based),恢复到指定的,历史上的某个时间点为止

recover database until time ‘yyyy-mm-dd hh24:mi:ss’;

2、基于撤销的不完全恢复(cancel-based),恢复到我们输入cancel命令时为止,这通常用于丢失联机重做日志文件或归档日志文件,当恢复到丢失的日志文件的时候,只能输入cancel命令,表示恢复到此为止

recover database until cancel

3、基于SCN号的不完全恢复(change-based),恢复到我们指定的、历史上的某个SCN,从本质上来说,这与基于时间的不完全恢复一样,除非我们能够确定要恢复到SCN号,否则建议使用基于时间点的恢复

recover database until cancel scn <integer>

建议在进行不完全恢复之前,将整个数据库进行冷备份,备份所有的数据文件、控制文件、联机重做日志文件,万一恢复失败,我们还能够将现场彻底还原到进行不完全恢复之前的状态

或者至少归档当前的联机日志文件、备份当前控制文件

alter system archive log current

alter database backup controlfile to <location>

不完全恢复之前,应该检查alter<SID>.ora,可能从中找出误操作的一些有关时间和SCN方面的信息

不完全恢复的步骤

1、关闭数据库,可以使用shutdown abort

2、从备份中还原所有的数据文件,整个数据库所有数据文件都恢复,因为SCN要整体推进到要恢复的时间点上,数据库要能够打开,所有数据文件头部记录的SCN号要一致

3、将数据库启动到mount状态

4、选择一种不完全恢复类型(time、cancel、change)

5、以resetlogs选项打开数据库,一旦使用了resetlogs选项打开数据库,则说明以后所有的重做记录不再需要,同时,数据库的日志序列号从1开始

在Oracle 10g数据库之前,如果我们以resetlogs方式打开数据库以后,没有做数据库的全备份,一旦再次发生介质损坏,导致数据文件的丢失,那么我们只能使用发出resetlogs之前的所做的备份进行恢复,最多只能恢复到发出resetlogs时这个时间点上,从而导致以resetlogs选项打开数据库以后,所有的数据变化丢失

因此,一旦resetlog打开数据库以后,第一个工作就是全备整个的数据库

到了Oracle10g之后,应用日志的算法有了改变,我们能够做到利用发出resetlogs之前做的备份,发出resetlogs之前的归档日志文件,发出resetlogs之后的归档日志、当前的联机重做日志文件,将数据库恢复到发出resetlogs之后介质损坏的那个时间点上

Oracle 10g之前,对数据库进行不完全恢复,需要对数据文件的状态进行查看v$datafile

1、确认所有的必要的数据文件都是在线的

2、只有使用了normal选项进行表空间离线的表空间、或只读表空间所对应的数据文件可以不需要在线的

3、如果不完全恢复期间,数据文件是离线的,那么他将不能够被恢复

4、如果表空间使用immediate进行了离线,同时,在使用resetlogs选项进行打开数据库以后,该数据文件仍然处于离线状态,那么该表空间需要被舍弃,并且重新创建,因为该文件需要使用resetlogs以前的日志进行介质恢复

clip_image026

使用resetlogs打开数据库以后,从resetlogs以后的一段重做记录确认不再使用了,打开数据库以后,操作正常进行,产生新的日志,对于现在这个数据库来说,新产生的日志是有意义的,从日志序列号1开始,resetlogs以前的日志不能够应用现在的数据库中了,现在的数据库已经不认识了,因为我们又从1开始了,以前的1已经不认识了。

使用normal选项使某个数据文件离线,离线以前,Oracle会发出文件级别的检查点,从而唤醒DBWn将内存中属于该文件的所有脏数据块写入数据文件,并且控制文件中检查点SCN与数据文件一致。

clip_image027

不能删除默认永久表空间

基于SCN的恢复和基于时间的恢复一样,只不过基于SCN的恢复更加精确。

前提都是

控制文件没有损坏、联机文件没有损坏、归档日志文件没有损坏

我们有意识的将数据库恢复到过去的某个点,例如为了恢复误删除

对于联机重做日志文件和归档日志文件的丢失,我们通常使用基于cancel的不完全恢复,下面的实验就是删除联机重做日志文件后的恢复

系统使用完了归档日志文件,要使用联机重做日志文件,因为使用的是以前的控制文件,因此无法知道哪一个是当前最新的联机日志文件,所有的归档用完以后,只会使用一个联机重做日志文件,这个联机重做日志文件就是shutdown时的current log,因为非current都进行了归档。日志组中在一个时刻只有current没有归档。

创建新的控制文件进行恢复,如果我们每次修改数据库结构时候,都将控制文件内容转储成为跟踪文件,并把其中的创建控制文件的SQL命令保存起来,那么当控制文件丢失的时候,我们也能够通过重建控制文件的方式,来恢复数据库。

创建新的控制文件,在丢失当前联机重做日志文件的情况下,进行不完全恢复。

1、系统的checkpoint会从redo log的current的first_change中取

2、文件SCN会从数据文件头部中取

我们此前做过trace文件的创建,数据库的结构没有发生变化,因此可以继续使用