Chinaunix首页 | 论坛 | 博客
  • 博客访问: 204568
  • 博文数量: 75
  • 博客积分: 2049
  • 博客等级: 大尉
  • 技术积分: 780
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-08 12:37
文章分类

全部博文(75)

文章存档

2011年(1)

2010年(9)

2009年(65)

我的朋友

分类: LINUX

2009-05-11 09:08:33

第七章:备份与恢复

7.1备份与恢复概述

常见故障类型:语句失败、用户进程失败、用户错误、实例失败、介质故障、网络故障。

7.2备份方法

n         逻辑备份

n         物理备份

7.3恢复原理

如果在恢复时我们有足够的归档日志和在线重做日志,那么通过恢复一个全备份,应用归档日志和重做日志,最终数据库就可以实现完全恢复。

7.4数据库的运行模式

n         归档模式(archivelog)

n         非归档模式(noarchivelog)

获取当前数据库的归档状态:

SQL> archive log list;

7.4.1如何改变数据库的归档模式

简要步骤:

n         修改必要的初始化参数

n         immediate方式关闭数据库

n         启动实例到mount状态

n         更改运行模式并打开数据库

(1)  修改初始化参数。和归档相关的几个主要参数如下:

n         log_archive_start:用于定义是否启动自动归档

n         log_archive_format:用于定义归档文件格式,可以采用缺省值

n         log_archive_dest:用于指定归档路径

如果数据库使用的是pfile,则可以直接修改,如果用的是spfile文件,则可以通过命令修改:

SQL> show parameter spfile;

SQL> alter system set log_archive_dest=’/opt/oracle/oradata/’;

SQL> alter system set log_archive_start=true scope=spfile;

(2)  关闭数据库

SQL> shutdown immediate;

(3)  启动数据库到mount状态

SQL> startup mount;

(4)  启用或停止归档模式。

SQL> alter database archivelog;

SQL> alter database noarchivelog;

7.4.2oracle 10g中的改变

oracle  10g中,log_archive_start参数已经废弃,只要启动数据库的归档模式,oracle就会启动到自动归档。

7.5oracle 10g的闪回恢复区(flash recovery area

查看闪回恢复区参数

SQL> show parameter db_recover;

db_recovery_file_dest

db_recovery_file_dest_size

以下几类主要文件可以在闪回区存放:

n         控制文件

n         归档的日子文件

n         闪回日志

n         控制文件和spfile自动备份

n         Rman备份集

n         数据文件拷贝

很多朋友习惯通过手工清除文件的方式释放空间,但是数据库无法得知这个空间释放。可以查看视图(v$recovery_file_dest)

SQL> select * from v$recovery_file_dest;

如果是删除归档日志文件,那么正确的做法应该是使用Rman登陆数据库进行crosscheck,再删除过期的备份,空间才能得到释放。常用命令如下:

RMAN> crosscheck archivelog all;

RMAN> delete expired archivelog all;

修改闪回区大小

SQL> alter system set db_recovery_file_dest_size=10G scope=both;

7.6逻辑备份与恢复

7.6.1使用EXP进行逻辑备份

n         EXP导出与字符集

导出客户端的字符集的设置会影响导出数据,所以应该设置导出客户端字符集和数据库一致。在Windows的命令行可以如下设置:

C:\set nls_lang=AMERICAN_AMERICA.ZHS16GBK

linux上可以设置

$export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

n         带查询子句的部分导出

以下是一个简单的范例:

C:\> exp eygle/eygle@dana  file=test.dmp tables=tquery query=’where object_id “<” 1000’

n         参数文件的使用

$ cat parfile.lst

userid=eygle/eygle

file=test.dmp

tables=tquery

query=”where object_id <1000 ”

$ exp parfile=parfile.lst

n         使用通配符进行模糊导出

$ exp eygle/eygle tables=e% file=a.dmp

这样,以字母E开头的表都被导出了。

n         排除部分表的导出

n         按日期区分文件名称的导出

很多时候,在导出备份时,我们希望在文件名中加入日期变量,以区分不同日期的导出文件。

以下介绍两种方法

(1)  通过数据库查询获取日期。

通过数据库查询可以获得需要的日期格式,在Windows上可以编写两个文件用于完成备份,一个是可执行的批处理文件,名称为startbak.bat,可以包含如下内容:

echo off

set oracle_sid=eygle

sqlplus eygle/eygle @expbydt.sql

第二个文件是expbydt.sql脚本

column today new_val dt

select to_char( sysdate,’ddmmyyyy’ ) today from dual;

host exp userid=eygle/eygle file=exp_eygle_&dt..dmp log=exp_eygle_&dt..log

exit

准备好了这两个文件之后,就可以通过命令行运行starbak.bat来执行逻辑备份了;

D:\backup>startbak.bat

D:\backup>echo off

(2)  通过操作系统获取日期

Windows可以通过如下命令获得:

D:\backup>echo %date:~0.10%

可以通过一个名为expbdt.bat的批处理文件来执行导出操作:

echo off

set oracle_sid=eygle

exp userid=eygle/eygle full=y file=d:\backup\exp_eygle_%date:~0.10%.dmp  log=d:\backup\exp_eygle_%date:~0.10%.log

执行的结果和上面的方法类似:

D:\backup>expdbt.bat

linux上的时间定义就显得更为简单:

exp eygle/eygle file=eygle_`date +%Y%M%d`

7.6.2使用IMP进行逻辑恢复

n         导入数据到不同的表空间

很多朋友在进行数据迁移时,希望把数据导入不同于系统的表空间,在导入之后却往往发现,数据导入了原表空间。这是因为如果缺省的原用户具有unlimited tablespace的权限,那么导入时会按照原来的位置导入数据,即导入到原表空间。

以下时一个测试范例,目标时将jive用户的数据导入到bjbbs用户下,就可以通过fromusertouser参数来将数据导入到不同的用户下:

$ imp bjbbs/passswd file=bj_bbs.dmp fromuser=jive touser=bjbbs grants=n;

但是导入完成发现,新导入的数据被存储在jive用户的缺省表空间USER

SQL> select table_name,tablespace_name from user_tables;

Drop掉用户,重新创建并回收用户unlimited tablespace权限:

SQL>       create user bjbbs identified by passwd

2                                    default tablespace bjbbs

3                                    temporary tablespace temp

4                                    /

SQL> grant connect ,resourse to bjbbs;

SQL> grant dba to bjbbs;

SQL> revoke  unlimited tablespace from bjbbs;

SQL> alter user bjbbs quota 0 on users;

SQL> alter user bjbbs quota unlimited on bjbbs;

重新导入数据:

$ imp bjbbs/passswd file=bj_bbs.dmp fromuser=jive touser=bjbbs grants=n;

n         使用indexfile进行导入

在有些特殊的情况下(如创建对象时强制指定非缺省表空间),以上的方法可能还是不能奏效,那么IMP工具还有另外一个参数可以使用,这个参数时INDEXFILE,当执行导入时指定参数INDEXFILE后,系统将创建表空间和索引等语句写到一个文件,通过编辑这个文件,就可以修改对象的创建语句,将表空间更改为希望的目标表空间,然后运行这个脚本完成对象创建,之后导入数据时至需要指定INGNORE=Y忽略创建错误,Oracle就可以将数据导入到正确的表空间,如果需要变更用户,则还需要指定FROMUSERTOUSER参数。

来看一个简单的测试,通过indexfile来执行一次导入(数据并不会被导入)

$ imp eygle/eygle file=test.dmp indexfile=test.idx rows=n

$ cat text.idx

缺省地,所有数据被标记为注释REM,修改TABLESPACE信息并去掉REM注释后该文件就可以SQL*PLUS调用来创建对象了。

7.6.3使用oracle 10g 数据泵(EXPDP/IMPDP

n         关于数据泵的概述

数据泵主要工作在服务器端,可以通过并行的方式快速装入或卸载数据,而且可以在运行过程中调整并行的程度,以加快备份或减少资源耗用。

n         数据泵使用

EXP不同,EXPDP增加了一个主要的新的参数:DIRECTORY

这个参数是用来定义一个路径,前面我们提到,数据泵主要在server端工作,导出文件需要写出到server端本地目录,这个DIRECTORY就对应的是server的路径。

可以自己创建一个DIRECTORY,也可以使用默认缺省的路径

SQL> create or replace directory expdir as  ’d:\oracle\expdir’

SQL> select * from dba_directories where directory_name=’EXPDIR’

然后可以对相应的用户进行授权:

SQL> grant read,write on directory expdir to eygle;

接下来可以通过EXPDP来导出操作了:

C:\>expdp eygle/eygle  dumpfile=eygle.dmp directory=expdir;

n         EXPDP/IMPDP的停止与重启

EXPDP/IMPDP的本质在于,通过API调用,把传统的EXP/IMP类交互模式的操作,转变为数据库内部的job任务,从而实现了任务的可中止与重启。

在数据库内部,重启动还依赖于另外一个数据结构MTmaster table ,任务主表),该表用于记录导入导出任务的进度。

接下来通过实例来看一下这几个参数的作用。

首先启动EXPDP执行导出操作,这里指定一个job_name,这个名称将是数据库中创建MT表的名称。

$ expdp eygle/eygle directory=dpdata dumpfile=full.dmp full=y job_name=expfull

 

在这里,可以通过Ctrl+C,退出当前交互模式,此时支持status等查看命令。

Export> status

如果此时要停止该任务,可以发出stop_job命令:

Export> stop_job

进入到数据库,可以看到为执行导出任务为所创建的MT

SQL> select * from tab where tname=’EXPFULL’;

接下来可以通过命令行再次连接到这个任务:

$expdp eygle/eygle attach=expfull

通过 start_job命令重启:

Export> start_job

n         EXPDP排除部分对象的导出

以下是solarisExclude 参数的使用范例,需要转义符“\

$ expdm  \’/ as sysdba\’ directory=DATA_PUMP_DIR schemas=rman dumpfile=expdp_rman.dmp EXCLUDE=TABLE:\”in\(DB\)”\;

最简单的方式仍然是将参数写入到一个参数文件来调用,这样可以避免复杂的参数转义

$cat parfile.par

directory=DATA_PUMP_DIR

schemas=rman

dumpfile=expdp_rman.dmp

INCLUDE=TABLE:”IN(‘DB’,’TS’)”

然后调用这个参数文件来执行导出:

$expdp \’/ as sysdba\’ parfile=parfile.par

7.7物理备份与恢复

7.7.1冷备份

以下几个查询在备份之前执行,以确认数据库文件以及存储路径

SQL> select name from v$datafile;

SQL> select member from v$logfile;

SQL> select name from v$controlfile;

冷备份步骤:

n         正常关闭数据库

n         备份所有重要的数据到备份目录

n         完成备份后启动数据库

7.7.2热备份

(1)  用户管理的热备份

用户管理的热备份通常步骤:

n         在备份之前需要显示的发出Begin Backup的命令

n         在操作系统拷贝备份文件

n         发出end backup命令通知数据库完成备份

n         备份归档日志文件

常见备份过程如下,这里以一个表空间的备份为例:

alter tablespace system begin backup;

host copy E:\ORACLE\ORADATA\EYGLE\SYSTEM01.DBF e:\oracle\orabak\SYSTEM01.DBF;

Alter tablespace system end backup;

当备份被激活时,可以通过v$backup视图来检查表空间的备份情况:

SQL> select * from v$backup

需要注意的是,当表空间置于热备份模式下,表空间数据文件头的检查点会被冻结,当热备份完成,发出 end backup命令,表空间数据文件检查点被重新同步,恢复更新:

(2)  额外Redo的生成

在使用Begin backup开始备份时,数据库会产生了比平常更多的日志,也就会产生更多的归档。这是因为在热备期间,oracle为了解决SPLIT BLOCK的问题,需要在日志文件中记录修改的行所在的数据块的前镜像,而不仅仅是修改信息

当拷贝数据文件的同时,数据库正好向数据文件写数据。这使得拷贝的文件中包含这样的database block,它的一部分来自于写操作之前,另一部分来自写操作之后。对于数据库来说,这个database blok本身并不一致,而是一个分裂块SPLIT BLOCK.这样的分裂块在恢复时并不可用。所以在热备状态下,对于变更的数据,oracl需要在日志记录整个变化的数据库的前镜像,这样如果在恢复的时候,数据文件中出现分裂块,oracle就可以通过日志文件中的数据库的前镜像覆盖备份,以完成恢复。

来看下测试,首先通过SYS用户连接数据库,确认SCOTT用户连接信息及日志信息:

SQL> alter system switch logfile;

SQL> select * from v$log;

SQL> select sid.serial# ,username from v$session;

分裂块产生的根本原因在于备份过程中引入了操作系统工具如cp工具,操作系统工具无法保证oracle数据块的一致性。如果使用RMAN备份,由于Rman可以通过反复读取获得一致的blok,从而避免SPLIT BLOCK的生成,所以不会产生额外的REDO,所以建议在备份时,应该尽量采用RMAN备份。

(3)  定制自适应的热备份脚本

以下是在生产库中经过实践的脚本范例:

首先看看crontab的定义

$crontab -l

30 2 * * 0-6 /opt/oracle/tools/hotbackup/startbak.sh

整个备份是通过一个叫startbak.sh的脚本启动的,这个脚本的主要内容如下:

Week=`date +”%w”`

Today=`date +”%m%d”`

Ps –ef|grep dbw0_$ORACLE_SID|grep –v grep >> /dev/null

If [ $? –eq 0 ];then

    If [ $week = “1” ];then

       $SH_HOME/genbaksql.sh

    Else

       $SH_HOME/dobakarch.sh

Fi

fi

如果周一则执行全备份,否则执行归档日志备份。

Genbaksql.sh这个脚本的主体部分包含如下语句:

Select  ‘PROMPT Begin backup tablespace’

||tablespace_name || ‘.’ || file_name ||CHR(10)

||‘alter tablespace’||tablespace_name||’begin backup;’||CHR(10)

 ||‘! cp’||file_name||’$BACKUP_FILE’||CHR(10)

 ||’alter tablespace’||tablespace_name||’end backup;’||CHR(10)

 From dba_data_files

Where status=’AVAILBLE’;

(4)  Oracle 10g的增强

oracle 10g中,新增命令用以简化用户管理的备份,现在可以通过alter database begin/end backup来进行数据库备份模式的切换,在10g之前,需要对每个表空间一一进行热备份设置:

SQL> alter database begin backup;

SQL> alter database end backup;

(5)  通过归档逐步恢复以缩短数据迁移时间

很多时候你可能会遇到这样的情况:一个大型数据库在同版本、同平台、异地异机的迁移,但是只有很少的停机时间,这看起来充满困难,但可以通过各种方法来缩短停机时间。在此情况下,可以通过一个热备份,应用归档恢复数据库到一个一致的状态,此时数据库可以被只读打开。之后可以继续应用归档进行恢复,最后只需要短时间停机,复制原数据库的在线日志和归档日志,控制文件到新库中,进行恢复,此时只需要极短时间即可完成恢复,这个方法只能适合在同平台的迁移过程中使用。

以下是一个示范步骤:

n         确定源数据库信息

查询源数据库归档情况,确认归档日志:

SQL> select name from v$archived_log;

归档当前日志

SQL> alter system switch logfile;

n         备份数据库

对源数据库进行备份,以下是简单的参考脚本:

Alter tablespace system begin backup;

Host copy E:\ORACLE\SYSTEM01.DBF  e:\oracle\orabak\SYSTEM01.DBF

Alter tablespace system end backup;

执行备份

SQL> @e:\a.sql

n         更改数据并归档部分日志

为了测试目的,再修改部分数据,并继续归档,数据库服务继续对外提供:

SQL> insert into eygle.test select * from eygle.test;

SQL> commit

SQL> alter system switch logfile;

SQL> insert into eygle.test select * from eygle.test;

SQL> commit

SQL> shutdown immediate;

n         执行恢复

在迁移过程中,可以将备份文件传输到目标主机,在目标主机恢复备份的数据文件,启动数据库:

SQL> startup mount

可以使用备份的控制文件执行恢复

SQL> recover database using backup controlfile until cancel;

应用了所有归档日志文件之后,可以将数据库以只读打开

SQL> alter database open read only;

因为源数据库的修改还在继续,可以关闭数据库,然后重新启动,应用归档日志,再次执行数据恢复:

SQL> shutdown immediate;

SQL> startup mount

SQL> recover database using backup controlfile until cancel;

恢复完成之后,数据库仍然以只读打开,进行数据确认,这样不断应用归档日志,迁移数据库可以和主数据库不断进行数据同步,在迁移停机时间到来时,就可以通过将源数据库所有日志归档,传输到迁移数据库应用,完成恢复,或者直接应用重做日志,完成恢复:

SQL> alter database open resetlogs;

(6)  用户管理备份的完全恢复

n         假定数据文件丢失,但是还有当前的控制文件和日志文件

首先restore数据文件到原有目录

此时如果尝试启动数据库,oracle就会提示需要介质恢复,这是根据控制文件和数据文件头的信息进行判断的

正常情况下可以先启动数据库到mount状态,然后开始恢复:

SQL> startup mount;

因为我们拥有最新的控制文件和所有归档及在线日志文件,所以简单通过一条命令执行恢复:

SQL> recover database;

 

7.7.3RMAN的备份与恢复

(1)  RMAN的备份保留策略

查看rman参数配置:

RAMN> show all;

查看废弃的备份

RAMN> report obsolete

设置REDUNDANCY设置为2

RAMN> configure retention policy to redundancy 2;

删除过期备份

RAMN>delete nopromt obsolete;

(2)  常用的crosscheck命令

当我们以手工方式删除了某些备份之后,RMAN将无法找到这些文件,但是这些文件在RMAN的备份记录中仍然存在。为了去除这些记录,可以参考以下实例:

RMAN> crosscheck backup;

RAMN> delete expired backup;

当手动删除了归档日志之后,可以用类似的命令来验证归档日志文件:

RMAN> crosscheck archivelog all

RAMN> delete noprompt expired archivelog all;

(3)  使用nocatalog方式进行数据库备份

可以通过如下方式设置控制文件自动备份:

C:\>rman target /

RMAN> configure controlfile autobackup on;

这个设置可以在RMAN中查询:

RMAN> show controlfile autobackup;

也可以在数据库中通过如下方式查询:

SQL> select * from v$rman_configuration;

注意下备份路径,由于在10g引入了闪回区,所以自动备份存储在闪回区中,如果不使用闪回区默认是存放在$ORACLE_HOME/dbs目录下

这里自动备份的控制文件缺省的命名规则:

c-IIIIIIIII-YYYYMMDD-QQ

其中c是控制文件,IDBID,YYYYMMDD是时间戳,QQ取决于序号00-FF

我们再来看一个全备份的处理:

RMAN> backup database tag=eygle090509

由于使用控制文件作为备份信息存储池,在完成备份后会写控制文件,这个写操作进而会触发控制文件的自动备份。

有了自动备份之后,在发生灾难后就可以使用自动备份恢复spfile文件和控制文件,恢复参数文件可以使用如下命令(通常恢复到一个临时目录下,以免覆盖当前文件,确认后再转移到缺省目录)。恢复spfile文件可以参考如下步骤:

RMAN> restore controlfile to ‘e:\temp\control01.ctl’ from autobackup;

如果数据库无法Mount,就不能使用如上方式恢复自动备份的控制文件或者参数文件。此时需要我们提供数据库的DBID,才能找到相应的自动备份用以恢复。如果无法得知DBID,那么可以直接指定自动备份集来恢复:

RMAN>restore controlfile to ‘e:\temp\control01.ctl’ from ‘c-2152029224-200905-09-00’

进一步,如果数据库无法nomount,那么恢复spfile文件时会遇到错误,此时可以手工编辑一个pfile文件启动实例,即可以进行spfile恢复,也可以使用RMAN启动默认实例,进行spfile文件恢复,启动默认实例:

RMAN> restore spfile to ‘e:\spfile.ora’ from ‘c-2152029224-200905-09-00’

(4)  Resetlogs/noresetlogs与控制文件

控制文件中记录着数据库的数据文件、日志文件、备份数据等信息,更为重要的,控制文件中还记录了数据库的检查点和SCN信息,这些信息在数据库恢复的过程中将起到关键作用。

可以通过如下一条命令将控制文件的创建语句备份到跟踪文件中:

SQL> alter database backup controlfile to trace;

SQL> @gettrcname

当数据库当前的redolog都可用时,可以通过noresetlogs参数重建控制文件,此时oracle能够从日志文件中读取redo信息,记录到控制文件中,由于redo中记录的信息足以重演所有提交成功的事务,所以最终能够实现完全恢复,成功打开数据库,这时的数据库就如同进行了一次断电之后的实例恢复,数据没有损失,重做日志可以继续向前写入。

下面在通过一次测试来看下这个过程:

首先在数据库正常的运行状态,可以执行一次控制文件转储:

SQL>alter session set events ‘immediate trace name controlf level 8’;

这个转储文件中包含数据库的检查点、redo thread信息、数据文件等信息。

接下来通过shutdown abort模拟一个数据库故障:

SQL> shutdown abort;

然后启动数据库到nomount状态,重建控制文件:

SQL> startup nomount;

SQL> create controlfile reuse database “mars” noresetlogs archivelog;

此时再来转储一次控制文件,检查log file record

经过恢复之后,数据文件达到了一致状态,checkpoint scnstop scn达到了一致,此时数据库就完成了恢复。

再来看下使用resetlogs的方式重建控制文件:

SQL> create controlfile reuse database “mars” resetlogs archivelog;

注意到此时控制文件的日志信息都是空的,oracle任务resetlogs方式下,当前的日志文件已经损失,那么就意味着oracle可能丢失提交成功的数据,恢复将是一次不完全的介质恢复。不完全恢复最终要求数据库通过resetlogs方式打开,resetlogs将会强制清空或重建在线日志。此时执行恢复必须使用backup controlfile选项:

SQL> recover database using backup controlfile until cancel;

在完成恢复后需要以resetlogs方式打开数据库:

n         在执行了不完全恢复之后

n         在使用了备份的控制文件进行恢复后

n         使用了带有resetlogs选项创建的控制文件恢复后。

(5)  数据文件头信息与数据库恢复

在数据文件头存在一系列的重要信息,这些信息包括检查点信息、数据库名称、软件版本信息等,在重建控制文件进行恢复时,可以从数据文件头获得这部分信息并写入重建的控制文件用于恢复。那么可以看一下在数据文件头都记录了哪些信息,通过如下命令我们可以将数据文件头信息转储出来:

SQL>alter session set events ‘immediate trace name file_hdrs level 10’;

在输出部分中的checkpointed at scn thread信息,这个两个信息记录了数据文件的检查的SCNRedo Byte AddressRBA)。这里的RBA包含了重要的恢复信息,代表最后完成的检查点对应的RBA,如果数据文件需要恢复,则需要根据这个RBA来决定应该从哪个日志文件开始。在通过重建控制文件进行恢复时,控制文件中不存在归档日志的相关信息,但是oracle仍然能准确提示我们需要的控制文件名称,那么这个信息从何而来呢?

SQL> recover database using backup controlfile;

这个信息就是来自数据库文件头。

RBA主要由以下三部分组成:

n         日志文件序号

n         日志文件块号

n         日志记录偏移量

具备了这些信息,再加上参数文件中定义的log_archive_format参数,oracle就可以推算出日志序列和日志文件名称,提示恢复。

阅读(1155) | 评论(0) | 转发(0) |
0

上一篇:英语笔记

下一篇:第七章:备份与恢复(2)

给主人留下些什么吧!~~