一:备份与恢复
1:备份:备份就是把数据库复制到转储设备的过程
2:恢复:恢复就是发生故障后,利用已备份的数据文件或控制文件,重新建立一个完整的数据库
2:四种故障类型
语句故障
用户进程故障
实例故障
介质故障
3:备份分类
物理与逻辑角度:物理备份、逻辑备份
备份策略角度:完全备份、增量备份、差异备份
4:恢复的分类
实例恢复:实例出现失败后,Oracle 自动进行的恢复
介质恢复:完全恢复、不完全恢复
二:恢复管理器(RMAN)
1:RMAN概念
是 DBA 的一个重要工具,用于备份、还原和恢复 Oracle 数据库
完成对目标数据库的控制文件、数据文件及归档日志文件以及SPFILE的联机备份
能够实现对数据库的完全或不完全的恢复操作
2:备份集
是一次备份的集合
3:备份片
一个或多个备份片组成一个备份集
三:导出导入
1:导出和导入的四种数据库对象
完全数据库
表
用户
表空间
四:闪回
为了使数据库能够从任何逻辑误操作中迅速恢复,Oracle推出了闪回技术
优点:
可以对行级和事务级的数据变化进行恢复
减少了数据恢复的时间,提高了数据库恢复的效率
操作简单,通过SQL语句就可以实现数据的恢复
闪回技术是数据库恢复技术历史上一次重大的进步,从根本上改变了数据恢复
实验部分:
一:rman工具
1:创建恢复目录
(1)创建表空间
[oracle@oracle ~]$ mkdir /u01/app/oracle/oradata/rmandb
[oracle@oracle ~]$ sqlplus sys/aptech AS SYSDBA
SQL> create tablespace rmants datafile
'/u01/app/oracle/oradata/rmandb/rmants.ora' size 20M;
(2)在恢复目录数据库中创建rman用户并授权
创建用户之前将数据库重启一下
SQL> shutdown;
SQL> startup;
SQL> create user c##rman identified by rman
default tablespace rmants
temporary tablespace temp
quota unlimited on rmants;
SQL> grant connect,resource to c##rman;
SQL> grant recovery_catalog_owner to c##rman;
(3)在恢复目录数据库中创建恢复目录
[oracle@oracle root]$ rman catalog c##rman/rman
RMAN> create catalog;
2:注册目标数据库到恢复目录
[oracle@oracle root]$ rman target sys/aptech
RMAN> connect catalog c##rman/rman;
RMAN> register database;
3:通道分配
(1)自动通道配置[ˈpærə lelɪzəm]平行
RMAN> configure device type disk parallelism 5;
RMAN> configure default device type to disk;
(2)手动通道配置
RMAN> run
{
allocate channel ch1 device type disk;
allocate channel ch2 device type disk;
allocate channel ch3 device type disk;
}
(3)显示通道配置参数
RMAN> show all;
RMAN> exit
可以在这里做个快照1,以防后面做错
(4)将oracle修改为归档模式(恢复数据库需要在归档模式下)
[oracle@oracle root]$ sqlplus sys/aptech AS SYSDBA
SQL> archive log list; 查看归档日志列表
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database archivelog;
SQL> alter database open;
SQL> exit
4:全库备份与恢复
(1)全库备份(备份在startup状态)
[oracle@oracle ~]$ mkdir -p /u01/app/bak
[oracle@oracle root]$ rman target sys/aptech
a:最基本的全库备份
RMAN> backup database; \自动分配通道,如果要增量备份,在backup后加上参数incremental level 0/1/2/3/4
b:自动分配通道进行全库备份
RMAN> backup database plus archivelog delete input; \自动分配通道,连同日志文件一起备份,备份完后删除归档日志
c:指定备份文件路径进行全库备份
RMAN> backup database format '/u01/app/bak/%U'; \自动分配通道,指定备份文件路径和命名格式
d:手动指定备份通道进行全库备份
RMAN> run
{
allocate channel ch1 device type disk;
backup database format '/opt/backup/rmanback/%U';
release channel ch1;
}
(2):全库备份的恢复(回复在startup mount状态)
[oracle@oracle root]$ rman target sys/aptech
RMAN> shutdown immediate
RMAN> startup mount
RMAN> restore database;
RMAN> recover database;
RMAN> alter database open;
5:备份和恢复表空间(都在startup状态)
(1)备份表空间
a:自动备份表空间
RMAN> backup tablespace users;
b:手动指定通道备份表空间
RMAN> run
{
allocate channel ch1 device type disk;
backup format '/opt/backup/rmanback/%U' (tablespace users,system,sysaux);
release channel ch1;
}
(2)恢复表空间
RMAN> run
{
alter tablespace users offline immediate;
restore tablespace users;
recover tablespace users;
alter tablespace users online;
}
6:数据文件的备份与恢复(都在startup状态)
(1)查看数据文件的文件号
[oracle@oracle ~]$ sqlplus sys as sysdba
SQL> col name for a50
SQL>select file#,rfile#,name from v$datafile
(2)备份3号数据文件
[oracle@oracle ~]$ rman target sys/aptech
RMAN> backup datafile 3;
(3)直接指定备份的数据文件进行备份备份
RMAN> backup datafile '/u01/app/oracle/oradata/orcl/sysaux01.dbf';
备份完后可以将sysaux01.dbf删掉,恢复后在看看是否回来了
b:数据文件的还原(还原3号数据文件)
RMAN> alter tablespace sysaux offline immediate;
RMAN> restore datafile 3;
RMAN> recover datafile 3;
RMAN> alter tablespace sysaux online;
RMAN> exit
二:使用数据泵技术实现逻辑备份
1:创建测试目录和用户,并授予用户权限
[oracle@oracle ~]$ mkdir /u01/app/bak
[oracle@oracle ~]$ sqlplus sys as sysdba
SQL> create directory dump_dir as '/u01/app/bak';
SQL> select * from dba_directories;
SQL> grant read,write on directory dump_dir to c##scott;
SQL> create user c##zhangsan identified by aptech;
SQL> create tablespace zhangsan datafile '/u01/app/oracle/oradata/orcl/zhangsan.dbf' size 20M;
SQL> grant connect,resource to c##zhangsan;
SQL> grant read,write on directory dump_dir to c##zhangsan;
SQL> grant unlimited tablespace to c##zhangsan;
SQL>exit
可以在此做个快照2,防止后面做错
2:导出scott的表emp,dept
(1)导出
[oracle@oracle root]$ expdp c##scott/scott directory=dump_dir dumpfile=scotttab.dmp tables=emp,dept
(2)删除表,模拟出故障
[oracle@oracle root]$ sqlplus sys/aptech AS SYSDBA
SQL> conn c##scott /scott
SQL> drop table emp; \删除掉emp表,
SQL> exit
(3)导入emp表
[oracle@oracle root]$ impdp c##scott/scott directory=dump_dir dumpfile=scotttab.dmp tables=emp,dept
(4)将表导入到c##zhangsan用户
[oracle@oracle root]$ impdp system/aptech directory=dump_dir dumpfile=scotttab.dmp tables=c##scott.dept,c##scott.emp remap_schema=c##scott:c##zhangsan
3导出scott用户模式(包含该用户所有的对象)
1)导出
[oracle@oracle root]$ expdp c##scott/scott directory=dump_dir dumpfile=scottschema.dmp schemas=c##scott
2)查看用户所包含的表
SQL> select 'drop table '||table_name||' purge;' from user_tables;
3)删除整个用户的所有表,模拟出故障
SQL> drop table BONUS purge;
drop table SALGRADE purge;
drop table EMP purge;
drop table DEPT purge;
4)导入用户scott
[oracle@oracle root]$ impdp c##scott/scott directory=dump_dir dumpfile=scottschema.dmp schemas=c##scott
5)将scott的用户模式导入到c##zhangsan的用户中
[oracle@oracle root]$ impdp system/aptech directory=dump_dir dumpfile=scottschema.dmp schemas=c##scott remap_schema=c##scott:c##zhangsan
4:导出表空间(需要提前创建一个表空间或直接使用上个实验创建的rmants表空间,也可以备份系统表空间system或其他内置的表空间,例如users表空间,但系统默认的表空间无法删除,不能模拟故障)
1)导出表空间
[oracle@oracle root]$ expdp system/aptech directory=dump_dir dumpfile=tablespaceusers.dmp tablespaces=zhangsan
2)删除表空间
[oracle@oracle root]$ sqlplus sys as sysdba
SQL> drop tablespace zhangsan INCLUDING CONTENTS;
3)创建一个新的同名的表空间,但是数据文件不能同名,或将原有的数据文件删除掉
SQL> create tablespace zhangsan datafile
'/opt/oracle/oradata/rmandb/zhangsan02.ora' size 20M;
4)导入表空间
[oracle@oracle root]$ impdp system/aptech directory=dump_dir dumpfile=tablespaceusers.dmp tablespaces=zhangsan
5:导入导出数据库(时间比较长)
[oracle@oracle root]$ expdp system/aptech directory=dump_dir dumpfile=full.dmp full=y
[oracle@oracle root]$ impdp system/aptech directory=dump_dir dumpfile=full.dmp full=y
三:使用闪回技术
1:设置闪回数据库
1)启用归档模式
[oracle@oracle root]$ sqlplus sys/aptech AS SYSDBA
SQL> shutdown immediate;
SQL> startup mount;
ORACLE instance started.
SQL> alter database archivelog;
2)建立闪回恢复区
SQL> alter system set
db_recovery_file_dest='/opt/oracle/flash_recovery_area' scope=both;
SQL> alter system set
db_recovery_file_dest_size=3G scope=both;
3)设置数据保留周期
SQL> alter system set db_flashback_retention_target=1440;
4)启用闪回日志
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database flashback on;
SQL> alter database open;
5)检查是否成功启用闪回恢复
SQL> show parameter db_recovery_file;
6)检查是否成功启用归档
SQL> archive log list;
7)检查是否成功启用闪回数据库
SQL> select flashback_on from v$database;
在此做个快照
8)取消闪回恢复区
(取消后就没了,还要重弄,做个快照方便一些,不做取消操作的话,可以不输入黄色代码,快照也就可以不做)
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database flashback off;
SQL> alter database open;
SQL> alter system set db_recovery_file_dest='';
快照回刚才的那个快照
2:闪回数据库
1)案例1:使用scn闪回数据库
SQL> select current_scn from v$database; \查询当前的SCN号,后面要用到
SQL> create table test1 (id number,name char(20));
SQL> insert into test1 values(1,'database');
SQL> commit;
SQL> shutdown immediate;
SQL> startup mount;
SQL> flashback database to scn 1179607; \1179607在前面的命令中可以看到,不要用书上的
SQL> alter database open resetlogs;
SQL> select * from test1; \验证test1时不存在,因为数据库闪回
查询最早闪回值(闪回时用的值不能小于该值)
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
SQL> select oldest_flashback_scn,
oldest_flashback_time
from v$flashback_database_log;
2)案例2:按照指定时间闪回数据库
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
SQL> select sysdate from dual;
SQL> set time on;
16:29:50 SQL> create table test2(
16:30:15 2 id number,name char(20));
16:30:47 SQL> insert into test2
16:31:39 2 values(1,'database');
16:32:02 SQL> commit;
16:33:42 SQL> shutdown immediate;
16:34:09 SQL> startup mount;
16:34:30 SQL> flashback database to
16:34:58 2 timestamp(to_timestamp('2015-07-11 16:29:02','yyyy-mm-dd hh24:mi:ss'));
16:37:21 SQL> alter database open resetlogs;
16:38:16 SQL> select * from test2; \验证时表test2已经不存在,因为数据库闪回
3:闪回表
1)案例1:使用scn闪回表
16:38:41 SQL> conn scott/tiger
16:44:13 SQL> set time on
16:44:22 SQL> create table test3(
16:45:01 2 id number primary key,name char(20));
16:45:27 SQL> insert into test3 values(1,'zhang');
16:45:49 SQL> commit
16:47:02 SQL> insert into test3 values(2,'zhao');
16:47:25 SQL> commit;
16:47:29 SQL> insert into test3 values(3,'wang');
16:48:22 SQL> commit;
16:51:53 SQL> exit
[oracle@oracle root]$ sqlplus sys/Oracle11g AS SYSDBA
SQL> grant select any dictionary to scott;
SQL> conn scott/tiger
SQL>set time on
16:52:22 SQL> select current_scn from v$database;
16:53:26 SQL> update test3 set name='liu' where id=1;
16:54:03 SQL> commit;
16:54:10 SQL> select * from test3;
16:55:03 SQL> delete from test3 where id=3;
16:56:10 SQL> commit;
16:56:22 SQL> select * from test3;
17:01:02 SQL> set time on
17:02:18 SQL> alter table test3 enable row movement;
17:03:00 SQL> flashback table test3 to timestamp
17:05:40 2 to_timestamp('2015-07-11 16:51:19','yyyy-mm-dd hh24:mi:ss');
17:07:32 SQL> select * from test3;
17:07:43 SQL> flashback table test3 to scn 1183525; \scn号前面能找到
17:09:10 SQL> select * from test3;
4:闪回删除
1)案例1:闪回删除
检查回收站是否启动,如果没启动要启动,默认是启动的
17:09:26 SQL> show parameter recyclebin
17:16:52 SQL> alter system set recyclebin=on deferred; \默认启动,此语句不必输入
17:17:22 SQL> conn scott/tiger
17:19:59 SQL> create table example(
17:20:14 2 id number primary key,
17:20:42 3 name char(20));
17:20:54 SQL> insert into example values(1,'before drop');
17:21:51 SQL> commit;
17:21:55 SQL> drop table example;
17:22:37 SQL> flashback table example to before drop
17:23:36 2 rename to new_example;
17:23:51 SQL> select * from new_example;
五:闪回查询技术
案例:闪回查询
17:24:23 SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
17:27:59 SQL> set time on
17:28:04 SQL> select empno,sal from scott.emp where empno=7844;
17:28:41 SQL> update scott.emp set sal=2000 where empno=7844;
17:30:05 SQL> commit;
17:30:08 SQL> update scott.emp set sal=2500 where empno=7844;
17:31:05 SQL> update scott.emp set sal=3000 where empno=7844;
17:31:45 SQL> commit;
17:31:53 SQL> update scott.emp set sal=3500 where empno=7844;
17:32:45 SQL> commit;
以下为查询当前的工资
17:32:48 SQL> select empno,sal from scott.emp where empno=7844;
以下为查询一小时前的工资
17:33:47 SQL> select empno,sal from scott.emp as
17:35:05 2 of timestamp sysdate-1/24 where empno=7844;
以下为查询第一个提交(commit)事物时的工资(第二个还没提交)
17:35:40 SQL> select empno,sal from scott.emp
17:37:56 2 as of timestamp to_timestamp('2015-07-11 17:31:45','yyyy-mm-dd hh24:mi:ss')
17:41:23 3 where empno=7844;
以下将数据恢复到之前的某个状态
17:42:45 SQL> update scott.emp set sal=(
17:43:05 2 select sal from scott.emp as of timestamp
17:43:28 3 to_timestamp('2015-07-11 17:32:45','yyyy-mm-dd hh24:mi:ss')
17:45:05 4 where empno=7844
17:45:19 5 )
17:45:23 6 where empno=7844;
17:45:37 SQL> commit;
17:45:41 SQL> select empno,sal from scott.emp where empno=7844;