备份数据库

1.备份内容

备份数据库是指备份数据库的所有数据文件,控制文件,参数文件和口今文件。下面先找到这些内容

数据文件
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
/u01/oradata/denver/system01.dbf
/u01/oradata/denver/undotbs01.dbf
/u01/oradata/denver/cwmlite01.dbf
/u01/oradata/denver/drsys01.dbf
/u01/oradata/denver/example01.dbf
/u01/oradata/denver/indx01.dbf
/u01/oradata/denver/odm01.dbf
/u01/oradata/denver/tools01.dbf
/u01/oradata/denver/users01.dbf
/u01/oradata/denver/xdb01.dbf

控制文件
SQL> select name from v$controlfile;
NAME
--------------------------------------------------------------------------------
/u01/oradata/denver/control01.ctl
/u01/oradata/denver/control02.ctl
/u01/oradata/denver/control03.ctl

可见数据文件和控制文件都在/u01/oradata/denver/下,但这个目录下还有redo*.log,在归档模式下一般重做日志不需要备份
SQL> ! ls /u01/oradata/denver
archive        control03.ctl  example01.dbf  redo01.log  system01.dbf  undotbs01.dbf
control01.ctl  cwmlite01.dbf  indx01.dbf     redo02.log  temp01.dbf    users01.dbf
control02.ctl  drsys01.dbf    odm01.dbf      redo03.log  tools01.dbf   xdb01.dbf

参数文件和口今文件
SQL> show parameter spfile;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
spfile                               string      ?/dbs/spfile@.ora

SQL> ! ls $ORACLE_HOME/dbs
initdenver.ora  init.ora  lkDENVER     spfiledenver.ora
initdw.ora      lkAAA     orapwdenver  spfiledenver.ora.bak

现在我们找到了要备份的所有内容,即
/u01/oradata/denver/*dbf(数据文件)
/u01/oradata/denver/*.ctl(控制文件)
$ORACLE_HOME/dbs/spfiledenver.ora(参数文件)
$ORACLE_HOME/dbs/orapwdenver(密码文件)

2.备份方法

备份数据库分为冷备和热备,冷备也叫数据一致性备份,是指关闭了数据库之后,把需要备份的内容CP出来,比较简单,只要能找到这些文件就能备份出来。
热备也叫数据库非一致性备份,是指在数据库open状态下备份数据文件和控制文件的方法。
冷备要关闭数据库会中断业务,也比较简单,在此不做讨论,下面使用热备来备份数据库,注意热备份一定要在归档模式下备份

SQL> archive log list
Database log mode              Archive Mode
Automatic archival              Enabled
Archive destination              /u01/oradata/denver/archive

由于在第一步已找到了要备份的文件,现在开始备份
SQL> alter database begin backup;
Database altered.
SQL>! cp /u01/oradata/denver/*.dbf /u01/backup/
SQL>alter database backup controlfile to '/u01/backup/backup.ctl'
SQL>! cp $ORACLE_HOME/dbs/spfiledenver.ora /u01/backup/
SQL>! cp $ORACLE_HOME/dbs/orapwdenver /u01/backup/
SQL>! alter database end backup;
SQL>alter system archive log current;

这样整个数据库就备份完了,备份完后应做测试是不是有效备份,只要是有效备份,那么就可以高枕无忧了。

如何单独备份表空间,控制文件,spfile等

2.备份表空间
表 空间在oracle中只是个逻辑概念,备份表空间其实是备份表空间下的数据文件,我们要找到表空间下对应的数据文件,把数据文件备出来。注意表空间备份只 适用于archivelog模式,备份表空间分为在表空间online备份和表空间offline备份,表空间脱机备份

SQL> select file_name from dba_data_files where tablespace_name='TEST1';
FILE_NAME
--------------------------------------------------------------------------------
/u01/test1.dbf
SQL> alter tablespace test1 offline;
Tablespace altered.
SQL> ! cp /u01/test1.dbf /u01/backup
SQL> alter tablespace test1 online;
Tablespace altered.
这样表空间test1就备份完了,因为表空间offline后就不能访问数据文件了,而且system表空间和正在使用的undo表空间不能脱机,所以这种方法很少用。

表空间联机备份
SQL> alter tablespace test1 begin backup;
Tablespace altered.
SQL> ! cp /u01/test1.dbf /u01/backup/
SQL> alter tablespace test1 end backup;
Tablespace altered.
备份完备。别外如果要备份只读表空间直接把数据文件拷贝出来就可以了,不用区分脱机和联机

3.备份控制文件
控制文件用于记录和维护数据库,当恢复数据库时,服务器进程和后台进程需要从控制文件中读取各种与备份相关的信息,如果控制文件损坏,则会导致备份信的丢失,当数据库配置发生改变时,一定要再单独备份控制文件
备份方法:
1.使用多元控制文件
2.备份到跟踪文件
3.建立控制文件副本
SQL> alter database begin backup;
Database altered.
SQL>alter database backup controlfile to '/u01/backup/backup.ctl'
#如果第二次使用这个命令,在最后加参数reuse(覆盖前一个)
SQL>alter database backup controlfile to '/u01/backup/backup.ctl' reuse;
SQL>! alter database end backup;
4.备份参数文件,口今文件
#参数文件
SQL>create pfile from spfile
SQL>! cp $ORACLE_HOME/dbs/spfiledenver.ora /u01/backup/
#口今文件
SQL>! cp $ORACLE_HOME/dbs/orapwdenver /u01/backup/
5.备份归档日志
在归档模式下,对数据库的所有操作都存到了归档日志里,因些物理恢复要用到归档日志,为了确保恢复可以顺利进行,还应该备份归档日志.备份归档日志很简单,找到文件CP出来就可以了.
#备份过去一天的归档日志
SQL> select name from v$archived_log where dest_id=1 and first_time>=sysdate-1;
NAME
--------------------------------------------------------------------------------
/u01/oradata/denver/archive/1_12.dbf
/u01/oradata/denver/archive/1_13.dbf
/u01/oradata/denver/archive/1_14.dbf
SQL>! cp /u01/oradata/denver/archive/1_12.dbf /u01/backup/
SQL>! cp /u01/oradata/denver/archive/1_13.dbf /u01/backup/
SQL>! cp /u01/oradata/denver/archive/1_14.dbf /u01/backup/

恢复分为完全恢复和不完全恢复,完全恢复是把数据库恢复到失败点,不完全恢复是当数据库出现文件损坏时,把数据库恢复到备份点和失败点之间的某个时间

完全恢复

先介绍在mount状态及open状态恢复数据的步骤,然后通过两个实例看如何一步步的把损坏的数据恢复回来.

一.Mount状态恢复步骤

1.启动数据库到mount状态
SQL>startup mount;
SQL>startup force mount;
2.转储备份的数据文件
SQL>! cp ‘backup.dbf’ ‘/xxx/aaa’
3.恢复数据文件
SQL>recover datafile file#
SQL>recover from ‘/u01/oracle/xxx.log’ datafile file#
SQL>recover database databasename
4.恢复数据库为open状态
SQL> alter database open;
Database altered.

二.open状态恢复步骤
1,数据库到open状态,损坏的数据文件脱机
如果现在数据库为shutdown状态,先到mount状态脱机损坏的数据文件,然后把数据库open
SQL>startup mount;
SQL>startup force mount;
SQL>select file#,error from v$recover_file;
SQL>alter database datafile file# offline;
SQL>alter database open
如果现在数据库为open状态,接在把损坏的数据文件脱机
SQL>select file#,error from v$recover_file ;
SQL>alter database datafile file# offline;
2.转储备份的数据文件
SQL>! cp ‘backup.dbf’ ‘/xxx/aaa’
3.恢复数据文件
SQL>recover datafile file#
SQL>recover from ‘/u01/oracle/xxx.log’ datafile file#
SQL>recover tablespace tablespacename;
4.数据文件联机
SQL>alter database datafile file# online;

三.实例
1.mount状态恢复system表空间
在system表空间建一个表t,并插入数据
SQL> alter system switch logfile;
SQL> create table t(i number) tablespace system;
SQL> insert into t values(1);
SQL> insert into t values(2);
SQL> insert into t values(3);
SQL> commit;
SQL> alter system switch logfile;
SQL> select * from t;
         I
-------------------
         1
         2
         3
关闭数据库,删除数据文件system01.dbf
SQL> shutdown immediate;
SQL> ! mv /u01/oradata/denver/system01.dbf /u01/oradata/denver/system01.dbf.bak
启动数据库
SQL> startup;
ORA-01157: cannot identify/lock data file 1 - see DBWR trace file
ORA-01110: data file 1: '/u01/oradata/denver/system01.dbf'
SQL> select status from v$instance;
STATUS
------------
MOUNTED
#只能启动到mounted状态
查看需要恢复的数据文件
SQL> col error format a30
SQL> select file#,error,change# from v$recover_file;
 FILE#   ERROR                           CHANGE#
---------- ------------------------------ -------------------------------------
   1     FILE NOT FOUND                      0
查看一下恢复需要的archivelog
SQL> col archive_name format a30
SQL> select sequence#,archive_name from v$recovery_log;
 SEQUENCE#    ARCHIVE_NAME
------------------- ----------------------------------------------
        29      /u01/oradata/denver/archive/1_29.dbf
#只要归档日志1_29.dbf还存在就能恢复
转储备份的数据文件
SQL> ! cp /u01/backup/system01.dbf /u01/oradata/denver/
SQL> select file#,error,change# from v$recover_file;
FILE#    ERROR                           CHANGE#
---------- ------------------------------ ------------------------------------------
   1                                        1661187
恢复
#1_29.dbf不在默认归档目录下
SQL> recover from '/u01/oradata/denver/archive/1_29.dbf datafile 1;
#1_29.dbf在默认归档目录下
SQL> recover datafile 1;
ORA-00279: change 1661187 generated at 05/05/2009 21:51:54 needed for thread 1
ORA-00289: suggestion : /u01/oradata/denver/archive/1_29.dbf
ORA-00280: change 1661187 for thread 1 is in sequence #29
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
auto
Log applied.
Media recovery complete.
改变数据库为open状态,查看是否恢复成功
SQL> alter database open;
Database altered.
SQL> select * from t;
         I
--------------------
         1
         2
         3
#可见恢复成功了
2.openu状态恢复未备份的数据文件
先新建一个表空间chenxy,并在上面建表chenxy,如下:
SQL> create tablespace chenxy datafile '/u01/oradata/denver/chenxy.dbf' size 2M;
SQL> create table chenxy(i number) tablespace chenxy;
SQL> insert into chenxy values(10);
SQL> insert into chenxy values(20);
SQL> commit;
SQL> alter system switch logfile;
SQL> select * from chenxy;
         I
-------------------
        10
        20
删除数据文件chenxy.dbf
SQL> ! mv /u01/oradata/denver/chenxy.dbf /u01/oradata/denver/chenxy.dbf.bak;
再查表chenxy就报错了
SQL> select * from chenxy;
ERROR at line 1:
ORA-00376: file 13 cannot be read at this time
ORA-01110: data file 13: '/u01/oradata/denver/chenxy.dbf'
查看需要恢复的文件
SQL> select file#,error,change# from v$recover_file;
   FILE#   ERROR                             CHANGE#
-------------- ------------------------------------------------------------- ----------
    13    FILE NOT FOUND                          0
SQL> select status from v$datafile where file#=13;
STATUS
-------
RECOVER
因为没有备份,使用控制文件新建数据文件
SQL> alter database datafile 13 offline;
#如果有备份的数据文件
SQL>! cp backup.dbf  '/u01/oradata/denver/chenxy.dbf';
#l因为没有备份,现在用控制文件新建数据文件
SQL> alter database create datafile '/u01/oradata/denver/chenxy.dbf';
SQL> select file#,error,change# from v$recover_file;
     FILE# ERROR                             CHANGE#
---------- ------------------------------ ----------------------------------------
        13                                      1662171
恢复并把数据文件13联机
SQL> recover datafile 13;
Media recovery complete.
SQL> alter database datafile 13 online;
现在查chenxy表
SQL> select * from chenxy;
         I
--------------------
        10
        20
恢复成功了,可见只要归档日志没有丢失,没有备份的数据文件也可以恢复回来.

其它
完全恢复的三个语句
recover database      用来恢复整个数据库的所有数据文件,只能在mount状态运行
recover tablespace     用来恢复某个表空间的所有数据文件,只能在open状态运行
recover datafile       用来恢复某个数据文件,在mount,open状态都可以运行

恢复数据库时用到的动态性能视图
v$recover_file       显示需要恢复的数据文件
v$recovery_log      显示恢复所需的归档日志,如果恢复所需的日志丢了,也就别想恢复了,
v$archived_log       显示所有的归档日志
v$loghist              显示归档日志SCN信息


不完全恢复

是指把数据库恢复到备份点和失败点之间某个时刻的状态,而且不完全恢复只适用于archivelog模式,不完全恢复可以基于时间点,基于SCN,基于控制文件或基于取消.下面用实例演示一下四种不完全恢复的用法.
1.基于时间的不完全恢复
一般当用户误删除表,误载断表,提交了错误数据后,DBA可以基于时间把数据库恢复到提交数据前的某一个状态
现在数据库中有一个表chenxy
SQL> select * from chenxy;
         I
----------------------
        10
        20
先做个全备份(数据文件)
SQL> shutdown immediate;
SQL> ! cp /u01/oradata/denver/*.dbf /u01/backup
现看当前时间并载断表
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2009-05-05 23:23:11
SQL> truncate table t;
Table truncated.
现在我们把表chenxy恢复到2009-05-05 23:23:11
1.关闭数据库
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
2.装载数据库
SQL> startup mount;
ORACLE instance started.
Total System Global Area  420549952 bytes
Fixed Size                   451904 bytes
Variable Size             385875968 bytes
Database Buffers           33554432 bytes
Redo Buffers                 667648 bytes
Database mounted.
3.复制所有数据文件备份
SQL> ! cp /u01/backup/*.dbf /u01/oradata/denver/
注意备份的时间点要在2009-05-05 23:23:11之前,查看备份时间
SQL> select file#,to_char(time,'yyyy-mm-dd hh24:mi:ss') from v$recover_file;
  FILE#   TO_CHAR(TIME,'YYYY-
------------- -------------------
     1    2009-05-05 23:20:18
     2    2009-05-05 23:20:18
     3    2009-05-05 23:20:18
     4    2009-05-05 23:20:18
     5    2009-05-05 23:20:18
     6    2009-05-05 23:20:18
4.恢复到特定时间点
SQL> recover database until time '2009-05-05 23:23:24';
Media recovery complete.
5.以resetlogs方式打开数据库,并查看表chenxy
SQL> alter database open resetlogs;
Database altered.
SQL> select * from chenxy;
         I
--------------------
        10
        20
    当以resetlogs方式打开数据库时,会重新建立重做日志,清空原有重做日志的内容(同时归档日志也全部删除了),而且过去的备份也不能直接使用了,现在重新备份所有数据文件和控制文件,并归档当前日志组
SQL> shutdown immediate;
SQL> ! cp /u01/oradata/denver/*.dbf /u01/backup
SQL> ! cp /u01/oradata/denver/*.ctl /u01/backup
SQL>startup
SQL> alter system switch logfile;
6.简单排错
因为选项resetlogs要清空重做日志,当出现如下错误ORA-00338时可用resetlogs打开数据库
SQL> startup
ORACLE instance started.
Total System Global Area  420549952 bytes
Fixed Size                   451904 bytes
Variable Size             385875968 bytes
Database Buffers           33554432 bytes
Redo Buffers                 667648 bytes
Database mounted.
ORA-00338: log 2 of thread 1 is more recent than controlfile
ORA-00312: online log 2 thread 1: '/u01/oradata/denver/redo02.log'
使用resetlogs打开后一定要做备份.
SQL> alter database open resetlogs;
Database altered.
SQL> select status from v$instance;
STATUS
------------
OPEN

2.基于SCN恢复

1.查看当前SCN号
SQL> select current_scn from v$database;
#或
SQL> select dbms_flashback.get_system_change_number scn from dual;
       SCN
--------------------
     1673513
1.关闭数据库
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
2装载数据库
SQL> startup mount;
ORACLE instance started.
Total System Global Area    420549952 bytes
Fixed Size                451904 bytes
Variable Size              385875968 bytes
Database Buffers           33554432 bytes
Redo Buffers              667648 bytes
Database mounted.
3.复制所有数据文件备份
SQL> ! cp /u01/backup/*.dbf /u01/oradata/denver/
注意备份的SCN号要小于1673513,查看备份的SCN
SQL> select file#,change# from v$recover_file;
     FILE#    CHANGE#
---------- ----------
       1      1673087
       2      1673087
       3      1673087
       4      1673087
       5      1673087
       6      1673087
       7      1673087
4.恢复到特定SCN
SQL> recover database until change 1673513;
Media recovery complete.
5.以resetlogs方式打开数据库,并查看表chenxy
SQL> alter database open resetlogs;
Database altered.
SQL> select * from chenxy;
         I
--------------------
        10
        20
6.重新备份所有数据文件和控制文件,并归档当前日志组
SQL> shutdown immediate;
SQL> ! cp /u01/oradata/denver/*.dbf /u01/backup
SQL> ! cp /u01/oradata/denver/*.ctl /u01/backup
SQL>startup
SQL> alter system switch logfile;


3.基于取消不完全恢复

其于取消恢复主要适用于因归档日志丢失,只能恢复到某一个时间的情况,恢复方法和前面两种一样,只是恢复时点不同.
恢复
SQL>shutdown immediate;
SQL>startup mount;
SQL>! cp /u01/backup/*.dbf /u01/oradata/denver/
SQL> recover database until cancel;
Media recovery complete.
SQL>alter database open resetlogs;

4.基于备份控制文件恢复

原理:当用户误删除一个表空间时,当前的控制文件就把此表空间的信息都删了,但是在备份的控制文件里还是它的信息,所以可以用备份的控制文件恢复表空间
删除一个表空间
SQL> drop tablespace chenxy including contents;
Tablespace dropped.
SQL> select * from chenxy;
select * from chenxy
ERROR at line 1:
ORA-00942: table or view does not exist
到alter日志找到删除时间
SQL> show parameter background_dump_dest
NAME                           TYPE        VALUE
------------------------------------ ----------- ------------------------------
background_dump_dest              string      /u01/admin/denver/bdump
 
SQL>! less /u01/admin/denver/bdump/alert_denver.log
Wed May  6 00:10:19 2009
drop tablespace chenxy including contents
Completed: drop tablespace chenxy including contents
恢复
SQL>shutdown immediate;
SQL>startup mount;
#此时把控制文件也复制过来
SQL>! cp /u01/backup/*.dbf /u01/oradata/denver/
SQL>! cp /u01/backup/*.bak /u01/oradata/denver/
SQL>recover database until time '2009-05-05 23:50:24' using backup controlfile
SQL>alter database open resetlogs
最后最好再做一个全备份.