一、备份与恢复概述
1、备份的分类
1、从物理与逻辑的角度分类
物理备份:对数据库操作系统的物理文件(如数据文件、控制文件和日志文件等)的备份。物理备份又可以分为脱机备份(冷备份)和联机备份(热备份),前者是在关闭数据库的时候进行的,后者是对正以归档日志方式运行的数据库进行备份。可以使用Oracle的恢复管理器(Recovery Manager RMAN)或操作系统命令进行数据库的物理备份。
逻辑备份:对数据库逻辑组件(如表和存储过程等数据库对象)的备份。逻辑备份的手段很多,如传统的EXP、数据泵EXPDP.数据库闪回技术及第三方工具。
2、从数据库的备份策略角度分类
完全备份:每次对数据进行完整的备份。当发生数据丢失的情况时,完全备份无须依赖其他信息即可实现100%数据恢复,其恢复时间最短且操作最方便。
增量备份:只对那些在上次完全备份或者增量备份后被修改的文件进行备份。增量备份的优点是备份数据量小,需要的时间短,缺点是恢复的时候需要依赖之前的备份记录,出现问题的风险较大。
差异备份:只备份那些自从上次完全备份之后被修改过的文件。从差异备份中恢复数据的时间较短,只需要两份数据——最后一次完全备份和最后一次差异备份,缺点是每次备份需要的时间较长。
2、恢复的分类
实例恢复:在Oracle实例出现失败后,Oracle自动进行的恢复。
介质恢复:当存放数据库的介质出现故障时所做的恢复。介质恢复又分为完全恢复和不完全恢复。
- 完全恢复:将数据库恢复到数据库失败时的状态。这种恢复是通过装载数据库备份并应用全部的重做日志做到的。完全恢复一般用于数据库发生崩溃时的数据恢复,但是用户的误操作(如删除表)一般不能通过完全恢复找回数据。
- 不完全恢复:将数据库恢复到数据库失败前的某一时刻的状态。这种恢复是通过装载数据库备份并应用部分重做日志做到的。进行不完全恢复后,必须在启动数据库时用resetlogs选项重设联机重做日志。如果用户执行了误操作,通过不完全恢复可以恢复到执行误操作之前的时间点的状态。
3、RMAN和EXPDP备份方式比对
对比指标 | RMAN备份 | EXPDP备份 |
---|---|---|
是否支持增量备份 | 支持 | 不支持 |
是否需要开启归档 | 需要 | 不需要 |
RPO | 0,无数据丢失 | >0,丢失备份以后的增量数据 |
RTO | >0,RTO取决于数据库的大小 | >0,RTO取决于数据库的大小 |
备份速度 | 备份速度快 | 备份速度慢于RMAN的备份速度 |
恢复速度 | 恢复速度快 | 恢复速度慢于RMAN的恢复速度 |
难易程度 | 需要专业DBA | 较为简单,普通运维人员也可以做 |
跨平台恢复 | 不支持 | 支持 |
跨版本恢复 | 不支持跨大版本的恢复 | 支持 |
核心数据库备份(7*24小时) | 适用 | 不适用(会丢失数据) |
大数据量数据库备份 | 适用大数据量的数据库备份 | 可用于500G以下数据库的备份,数据量大的库备份和恢复速度太慢,效果很差 |
按用户备份 | 不支持 | 支持 |
按数据表备份 | 不支持 | 支持 |
单独备份某数据对象 | 不支持 | 可以单独导出表、索引、存储过程、DB_LINK、JOB等数据对象 |
备份片存放路径 | 本地磁盘或ASM磁盘组 | 本地磁盘 |
二、使用RMAN工具实现备份恢复
RMAN是Oracle的一个重要工具,用于备份和恢复数据库文件、归档日志和控制文件,也可以用来执行完全或不完全的数据库恢复。RMAN有两种不同的用户接口:命令行方式、API(Application Programming Interface,应用程序编程接口)方式(用于集成到第三方的备份软件中)。它具有如下优点:
- 支持在线热备份。
- 可以实现增量备份,不用每次都全量备份数据,节省备份空间和时间。
- 配合数据库归档日志文件和日志文件能够实现100%数据的恢复,保证不丢失数据。
- 备份、恢复的速度快,节省备份和恢复的时间。
- 备份时只抽取已经存放数据的数据块,对预占用的空间不做备份,因此备份片体积小,节省备份空间。
- RMAN备份的数据可实现自动管理,包括命名,检查备份片有效性,清理过期备份等。
- 在备份与恢复操作时,使用简单的指令就可以实现备份与恢复,执行过程完全由RMAN维护,方便快捷。
- RMAN可以指定压缩备份、加密备份等场景,解决各种不同的备份需求。
适用场景
- 适用于7*24小时数据库的备份。
- 适用于对数据库数据安全性要求比较高的核心数据库系统,RMAN备份配合归档日志,可充分保障数据安全。
- 适合数据量较大的数据库的备份(500G以上),可以基于一个全备每天做增量备份,节省备份时间和空间。
1、RMAN组件
1、目标数据库(Target Database)
目标数据库就是需要RMAN对其进行备份与恢复的数据库。RMAN可以备份数据文件,控制文件归档日志、spfile。
2、服务器会话(Server Session)
RMAN启动数据库上的Oracle服务器进程,建立一个与目标数据库的会话,并通过目标数据库上的服务器进程进行备份、还原、恢复的实际操作。
3、RMAN资料库(RMAN Repository)
RMAN使用过程中用到的控制信息是一些关于备份、归档日志及RMAN活动的元数据。
4、恢复目录(Recovery Catalog)
恢复目录是建立在RMAN恢复目录数据库上的一种schema对象,用于保存RMAN资料库数据。
恢复目录是一个可选的组件。RMAN会将资料库数据记录在目标数据库的控制文件中,但这样不够安全,因为一旦目标数据库的控制文件损坏就意味着所有的RMAN备份失效。因此建议在单独的一个数据库中建立恢复目录另外保存一份资料库数据。
5、MML
MML(Media Management Layer,介质管理层)是第三方工具或软件,用于管理对磁带的读写与文件的跟踪管理。如果想直接通过RMAN备份到磁带上,就必须配置介质管理层,介质管理层的工具和RMAN共同配合完成备份与恢复。
6、快闪恢复区
快闪恢复区是Oracle数据库用于保存所有与恢复相关的文件的默认磁盘位置。这些相关文件包括归档日志、RMAN备份、控制文件自动备份、复用的控制文件和重做日志副本及闪回日志文件。
7、辅助数据库
在正常使用时,RMAN会与目标数据库一起使用,如果创建了恢复目录数据库,那么RMAN也会与恢复目录数据库一起使用。在某些情况下,人们希望创建辅助数据库。辅助数据库是使用RMAN从目标数据库的备份中创建的新数据库,能够作为备用数据库使用。在产品数据库出现故障时,能够在不丢失任何数据及停机时间最短的情况下切换至备用数据库。
2、备份策略
场景 | 全备 | 增量备份 | 归档日志备份 |
---|---|---|---|
1. 全库备份小于300G。 2. 每周增量数据小于20G。 3. 每天归档量小于20G。 | 周末1个全备+归档日志备份。 | 无 | 无 |
1. 全库备份小于1T,大于300G。 2. 每周增量数据大于20G,小于50G。 3. 每天归档量小于200G,大于20G。 | 周末1个全备+归档日志备份。 | 周二、周四各1个增量备份+归档日志备份。 | 每天1个或多个归档日志备份。 |
1. 全库备份大于1T。 2. 每周增量数据大于50G。 3. 每天归档量大于200G。 | 每月1个或2个全备+归档日志备份。 | 全备日以外,每天1个增量备份+归档日志备份。 | 每天多个归档日志备份,比如4小时一次。 |
一次全库备份的空间使用率可以通过以下查询语句预估
select sum(bytes)/1024/1024/1024 from dba_segments;
增量大小以实际为准
归档日志数据量的评估,可通过如下方法计算得出:Redo Log Size(日志文件组大小)* 每天Redo Log的切换次数。
# 查询Redo Log Size
SQL> select bytes/1024/1024 "SIZE MB" from v$log;
# 每天Redo Log的切换次数,即每天的归档日志数量,取所有节点一周的总量,然后除以7,就是一天的归档日志数量
SQL> select count(*) from v$log_history where first_time >=trunc(sysdate)-7 and first_time < trunc(sysdate);
3、创建恢复目录
1、创建表空间
# mkdir -p /u01/app/oracle/oradata/rmandb
# chown -R oracle:oinstall /u01/app/oracle/oradata/rmandb/
# su - oracle
Last login: Wed Jul 31 18:45:40 CST 2019 on pts/0
$ sqlplus / as sysdba
SQL> startup
SQL> create tablespace rmants datafile '/u01/app/oracle/oradata/rmandb/rmants.dbf' size 20M;
表空间已创建。
2、在恢复目录数据库中创建RMAN用户并授权
RMAN用户必须被授予RECOVERY_CATALOG_OWNER权限
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;
授权成功。
SQL> exit
从 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 断开
3、在恢复目录数据库中创建恢复目录
$ rman catalog c##rman/rman
RMAN> create catalog tablespace rmants;
恢复目录已创建
RMAN> exit
恢复管理器完成。
4、注册目标数据库到恢复目录
$ rman target sys/orcle;
RMAN> connect catalog c##rman/rman
连接到恢复目录数据库
RMAN> register database;
注册在恢复目录中的数据库
正在启动恢复目录的全部重新同步
完成全部重新同步
RMAN> exit
恢复管理器完成。
如果目标数据库的表空间与数据文件等发生变化,则目标数据库的控制文件会被改写,此时,为了保持恢复目录与目标数据库控制文件的同步,可以运行以下命令。
RMAN> resync catalog;
5、通道分配
使用RMAN进行备份和恢复操作时,必须进行通道的分配。一个通道是RMAN和目标数据库之间的一个连接,通道指定了某种类型的设备用于备份和恢复,RMAN可以使用的通道设备包括磁盘(disk)与磁带(sbt,system backup to tape)两种。
通道分配可以自动或手动进行。
1、自动通道配置
RMAN> CONFIGURE DEVICE TYPE disk PARALLELISM 5; # 指定RMAN可以打开五个磁盘通道
RMAN> CONFIGURE DEFAULT DEVICE TYPE TO disk; # sbt/disk:磁带/磁盘。
2、手动通道配置
RMAN > run
{
allocate channel chl device type disk;
allocate channel ch2 device type disk;
allocate channel ch3 device type disk;
}
3、显示通道配置参数
RMAN > show all;
4、备份与恢复
1、配置备份集文件的格式(Format)
使用BACKUP命令进行备份时,需要明确备份文件的存储路径及文件名称格式。其路径和格式可以使用FORMAT参数进行统一设置。FORMAT格式由两部分组合,即存储路径和文件名称格式。
FORMAT命令格式如下:
FORMAT '格式字符串'
其中,格式字符串的文件名称部分可以使用替换变量。例如,FORMAT'/backup/rmanback/%U'
。
常用的替换变量如下。
- %c:备份片的复制数。
- %d:数据库名称。
- %D:位于该月中的第几天(DD)。
- %M:位于该年中的第几月(MM)。
- %F:一个基于DBID(Database ldentifier,数据库标识符)的唯一的名称,它的形式为C-||||||||-YYYYMMDD-QQ.其中||||||||为该数据库的 DBID,YYYYMMDD 为日期,QQ是一个1~256的序列。
- %n:数据库名称,向右填补到最大8个字符。
- %u:一个8个字符的名称,它是根据备份集个数与创建时间信息生成的。
- %p:该备份集中的备份片号,从1开始到创建的文件数。
- %U:系统生成的一个唯一文件名,对于备份片来说,它的含义相当于
%u_%p_%c
。 - %s:备份集的号。
- %t:备份集时间戳。
- %T:年月日格式(YYYYMMDD)。
如果没有使用FORMAT指定存储路径和文件名称格式,则默认情况下BACKUP命令所产生的备份集将存储在快闪恢复区中,RMAN自动使用%U来确保文件名称不会重复。
2、在归档方式下备份与恢复(完全恢复)
将数据库设置为归档模式,数据库实例要处于启动状态,数据库已经加载或打开状态
1、开启归档模式
# mkdir -pv /arch
# chown -R oracle:oinstall /arch
# su - oracle
$ sqlplus / as sysdba
SQL> archive log list; # 查看数据库是否开启归档
Database log mode No Archive Mode # 没有开启归档
Automatic archival Disabled
Archive destination /u01/app/oracle/product/11.2.0.3/db_1/dbs/arch
Oldest online log sequence 42
Current log sequence 43
SQL> alter system set log_archive_dest_1='location=/arch' scope=spfile; # 设置归档日志目录,重启后生效
SQL> shutdown immediate; # 关闭数据库
SQL> startup mount # 启动到挂起模式
SQL> alter database archivelog; # 更改归档模式
SQL> alter database archivelog start; # 启用归档模式并立即开始归档
SQL> ALTER DATABASE OPEN; # 打开数据库
SQL> archive log list;
Database log mode Archive Mode # 开启归档
Automatic archival Disabled
Archive destination /u01/app/oracle/product/11.2.0.3/db_1/dbs/arch
Oldest online log sequence 42
Current log sequence 43
2、备份和恢复整个数据库
备份
# mkdir -pv /u01/app/bak/
# # chown -R oracle:oinstall /u01/app/bak/
$ rman target sys/oracle
RMAN> backup database; # 自动分配通道,FORMAT默认使用%U,备份集存储在数据库快闪恢复区内;备份文件包括数据文件、控制文件、重做日志文件和参数文件
RMAN> backup database plus archivelog delete input; # 如果还要包含归档日志文件,则要加上plus archivelog关键字.delete input的意思是在备份完成后,删除archivelog文件
RMAN> backup database format '/u01/app/bak/%U'; # /u01/app/bak目录需要提前创建
# 手动分配通道,备份数据库
RMAN > run
{
allocate channel chl device type disk;
backup database format '/u01/app/bak/%U';
release channel chl;
}
恢复
$ rman target sys/oracle
RMAN> startup mount # 全库备份的恢复,数据库要在mount的状态下执行
RMAN> restore database;
RMAN> recover database;
RMAN> alter database open;
3、备份和恢复表空间
备份
RMAN> backup tablespace users; # 表空间备份
# 在RUN命令中备份表空间
RMAN > run
{
allocate channel chl device type disk;
backup tablespace users format '/u01/app/bak/%U';
release channel ch1;
}
恢复
# 如果只丢失了特定的表空间的数据文件,那么可以选择只恢复这个表空间,而不是恢复整个数据库,表空间恢复可以在不关闭数据库的情况下进行,只需要将需要恢复的表空间offline
RMAN > run
{
alter tablespace users offline immediate;
restore tablespace users;
recover tablespace users;
alter tablespace users online;
}
4、数据文件的备份和恢复
备份
$ sqlplus / as sysdba
SQL> col file_name for a50;
SQL> col file_id for 99999;
SQL> set line 100
SQL> col TABLESPACE_NAME for a10;
SQL> select file_id,file_name,tablespace_name from dba_data_files;
FILE_ID FILE_NAME TABLESPACE_NAME
------- -------------------------------------------------- ------------------------------
1 /u01/app/oracle/oradata/orcl/system01.dbf SYSTEM
3 /u01/app/oracle/oradata/orcl/sysaux01.dbf SYSAUX
4 /u01/app/oracle/oradata/orcl/undotbs01.dbf UNDOTBS1
7 /u01/app/oracle/oradata/orcl/users01.dbf USERS
13 /u01/app/oracle/oradata/rmandb/rmants.dbf RMANTS
14 /u01/app/oracle/oradata/rmandb/tab1.dbf TAB1
15 /u01/app/oracle/oradata/rmandb/tab2.dbf TAB2
已选择 7 行。
SQL> quit
$ rman target sys/oracle
RMAN> backup datafile 15; # 进行备份。15为查询需要备份的表所对应的FILE_ID
RMAN> quit
模拟15号文件丢失
$ mv /u01/app/oracle/oradata/rmandb/tab2.dbf /u01/app/oracle/oradata/rmandb/tab2.dbf.bak1
恢复
$ rman target sys/oracle
RMAN> run
RMAN> alter tablespace sysaux offline immediate;
RMAN> restore datafile 15;
RMAN> recover datafile 15;
RMAN> alter tablespace sysaux online;
RMAN> exit
$ ls /u01/app/oracle/oradata/rmandb/
rmants.dbf tab1.dbf tab2.dbf tab2.dbf.bak tab2.dbf.bak1
3、不完全恢复
创建测试数据
$ sqlplus /as sysdba
SQL> archive log list;
SQL> create tablespace tab1 datafile '/u01/app/oracle/oradata/rmandb/tab1.dbf' size 10m; # 创建一个表空间和表
SQL> create table tab1 (id int); # 创建表tab1
SQL> insert into tab1 values(1); # 向表tab1中添加记录
SQL> commit;
SQL> ho mkdir /u01/app/bak # 执行she11命令,创建目录
SQL> exit
备份
$ rman target sys/oracle
RMAN> backup database format '/u01/app/bak/%U';
RMAN> select systimestamp from dual; # 数据库正常时查看时间点
SYSTIMESTAMP
-------------------------------------
20-5月 -20 03.12.31.337814 下午 +0
RMAN> exit
恢复管理器完成。
模拟数据丢失
$ sqlplus sys/oracle as sysdba
SQL> drop table tab1;
表已删除。
SQL> commit;
提交完成。
不完全恢复
SQL> shutdown immediate;
SQL> startup mount
SQL> exit;
$ rman target sys/oracle
RMAN> restore database; # 恢复数据文件
RMAN> recover database until time "to_date('2020-05-20 15:12:31','yyyy-mm-dd hh24:mi:ss')"; # 执行不完全恢复,时间为正常时查询的时间点
从位于 20-5月 -20 的 recover 开始
使用通道 ORA_DISK_1
正在开始介质的恢复
介质恢复完成, 用时: 00:00:00
在 20-5月 -20 完成了 recover
RMAN> alter database open resetlogs; # 不完全恢复一定要使用resetlogs选项
已处理语句
RMAN> select * from tab1;
ID
----------
1
RMAN> exit
恢复管理器完成。
完全恢复可以将数据库恢复到最近的正常状态,即使用户误删除数据,只要数据库运行正常,也认为是正常状态,因此如果用户误删除了数据,通过完全恢复是无法找回的。而不完全恢复可以将数据库恢复到指定的时刻,如用户在t1时刻误删除了数据,那么只要通过不完全恢复将数据库恢复到t1之前的时刻即可找回丢失的数据。
三、使用数据泵技术实现逻辑备份
1、逻辑备份概述
逻辑备份是创建数据库对象的逻辑副本,并存入一个二进制转储文件的过程。从本质上来说,逻辑备份与恢复就是对数据库实施数据的导出和导入过程。
1、导出
导出即数据库的逻辑备份,其实质是读取一个数据库记录集并将这个记录集写入一个文件(扩展名通常是dmp)中。这些记录的导出与其物理位置无关。
2、导入
导入即数据库的逻辑恢复,其实质是读取被导出的二进制转储文件并将其恢复到数据库。
2、使用数据泵技术导入/导出
EXPDP数据泵备份是采用了数据泵(Data Dump)技术,使运维人员可以将数据库元数据(对象定义)和数据快速导出到备份存储的一种备份方式。效果类似于生活中常见的水泵,将池中的水抽取到另一个位置存储。
适用场景
- 适合非7*24小时数据库的备份。
- 适合非重点业务数据库,可以承受丢失部分最新数据,并且数据量小于500G的数据库的备份。
- 适合没有开启归档模式的数据库的备份。(一般非重点业务数据库可以运行在非归档模式)
1、创建—个操作目录
# su - oracle
Last login: Wed Jul 31 18:45:40 CST 2019 on pts/0
$ sqlplus / as sysdba
SQL> startup
SQL> exit
$ exit
登出
# mkdir /u01/app/backup
# chown -R oracle:oinstall /u01/app/backup/
# su - oracle
Last login: Fri May 22 14:28:06 CST 2020 on pts/0
$ sqlplus / as sysdba
SQL> create directory dump_dir as '/u01/app/backup'; # 如果提示已存在,请忽略
目录已创建。
2、授予用户操作dump_dir目录的权限
SQL> grant read,write on directory dump_dir to c##scott;
授权成功。
3、创建测试用户user1并授权
SQL> create user c##user1 identified by 123456;
用户已创建。
SQL> grant connect,resource to c##user1;
授权成功。
SQL> grant read,write on directory dump_dir to c##user1;
授权成功。
SQL> grant unlimited tablespace to c##user1;
授权成功。
SQL> exit
4、导出c##scott用户的emp和dept表
$ expdp c##scott/123456 directory=dump_dir dumpfile=scotttab.dmp tables=emp,dept
5、导入scott用户表(模拟损坏)
$ sqlplus c##scott/123456
SQL> select table_name from user_all_tables;
TABLE_NAME
--------------------------------------------------------------------------------
DEPT
EMP
BONUS
SALGRADE
SQL> drop table emp;
表已删除。
SQL> exit
$ impdp c##scott/123456 directory=dump_dir dumpfile=scotttab.dmp tables=emp
$ sqlplus c##scott/123456
SQL> select table_name from user_all_tables;
TABLE_NAME
--------------------------------------------------------------------------------
DEPT
BONUS
SALGRADE
EMP
SQL> exit
6、将导出的c##scott用户的dept和emp表导入给c##user1
$ impdp system/oracle directory=dump_dir dumpfile=scotttab.dmp tables=c##scott.dept,c##scott.emp remap_schema=c##scott:c##user1
$ sqlplus c##user1/123456
SQL> select table_name from user_all_tables;
TABLE_NAME
--------------------------------------------------------------------------------
DEPT
EMP
SQL> exit
7、导出与导入scott用户模式
$ expdp c##scott/123456 directory=dump_dir dumpfile=scottschema.dmp schemas=c##scott # 导出c##scott.emp表
$ sqlplus c##scott/123456 # 用scott用户连接数据库,删除emp表
SQL> drop table emp;
表已删除。
SQL> select * from emp; # emp已不存在
select * from emp
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
SQL> exit
$ impdp c##scott/123456 directory=dump_dir dumpfile=scottschema.dmp schemas=c##scott # 导入scott.emp表
$ sqlplus c##scott/123456 # 用scott用户连接数据库
SQL> col ENAME for a10
SQL> col JOB for a10
SQL> set line 120
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- ------------ ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12月-80 800 20
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7566 JONES MANAGER 7839 02-4月 -81 2975 20
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
7698 BLAKE MANAGER 7839 01-5月 -81 2850 30
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
7839 KING PRESIDENT 17-11月-81 5000 10
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- ------------ ---------- ---------- ----------
7900 JAMES CLERK 7698 03-12月-81 950 30
7902 FORD ANALYST 7566 03-12月-81 3000 20
7934 MILLER CLERK 7782 23-1月 -82 1300 10
已选择 14 行。
SQL> exit
8、导入与导出表空间
$ sqlplus system/oracle
SQL> create tablespace user01
2 datafile '/u01/app/oracle/oradata/user01.dbf' size 10m;
表空间已创建。
SQL> create table t1(id int) tablespace user01;
表已创建。
SQL> insert into t1 values(1);
已创建 1 行。
SQL> commit;
提交完成。
SQL> exit
从 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 断开
$ expdp system/oracle directory=dump_dir dumpfile=tablespaceusers.dmp tablespaces=user01
$ sqlplus system/oracle
SQL> drop table t1;
表已删除。
SQL> exit
从 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 断开
$ impdp system/oracle directory=dump_dir dumpfile=tablespaceusers.dmp tablespaces=user01
$ sqlplus system/oracle
SQL> select * from t1;
ID
----------
1
SQL> exit
9、导入与导出数据库
$ expdp system/oracle directory=dump_dir dumpfile=full.dmp full=y # 导出
$ impdp system/oracle directory=dump_dir dumpfile=full.dmp full=y # 导入
四、闪回技术
1、闪回技术概述
闪回技术包括以下各项。
- 闪回查询(Flashback Query):查询过去某个时间点或某个SCN(System Change Number,系统更改号)值时表中的数据信息。
- 闪回版本查询(Flashback Version Query):查询过去某个时间段或某个SCN段内表中数据的变化情况。
- 闪回事务查询(Flashback Transaction Query):查看某个事务或所有事务在过去一段时间内对数据进行的修改。
- 闪回数据库(Flashback Database):将数据库恢复到过去某个时间点或某个SCN值时的状态。
- 闪回删除(Flashback Drop):将已经删除的表及其关联对象恢复到删除前的状态
- 闪回表(Flashback Table):将表恢复到过去的某个时间点或某个SCN值时的状态。
2、闪回恢复区
1、含义
Oracle推荐指定一个闪回恢复区(Flash Recovery Area)作为存放备份与恢复相关文件的默认位置,这样Oracle就可以实现自动的基于磁盘的备份与恢复(Automatic Disk-Based Backup and Recovery)。那么,什么是闪回恢复区?简单地说,闪回恢复区就是一块用以存储恢复的相关文件的存储空间,允许用户集中存储所有恢复的相关文件。如下几种文件都可以放到闪回恢复区中。
- 控制文件。
- 归档的日志文件。
- 闪回日志。
- 控制文件和SPFILE自动备份。
- BMAN备份集。
- 数据文件复制。
2、设定闪回恢复区
如果使用DBCA创建的数据库,在安装时可以设定闪回恢复区的位置及大小。闪回恢复区主要通过以下三个初始化参数来设置和管理。
- db_recovery_file_dest:指定闪回恢复区的位置。
- db_recovery_file_dest_size:指定闪回恢复区的可用空间大小。
- db_flashback_retention_target:控制闪回日志中数据保留的时间,或者说,希望闪回数据库能够恢复到的最早的时间点,单位为min,默认为1440min,也就是一天。当然,实际上可回退的时间还取决于闪回恢复区的大小,因为里面保存了回退所需要的闪回日志,所以这个参数要和db_recovery_file_dest_size参数配合修改。
如果要撤销闪回恢复区,只需将初始化参数db_recovery_file_dest的值清空即可。
3、设置闪回数据库
1、启用归档模式
闪回数据库只能处于归档状态
$ sqlplus / as sysdba
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database archivelog;
数据库已更改。
SQL> exit
$ exit
2、建立闪回区
# mkdir -p /u01/app/oracle/flash_recovery_area
# chown -R oracle:oinstall /u01/app/oracle/flash_recovery_area
# su - oracle
Last login: Fri May 22 14:30:51 CST 2020 on pts/0
$ sqlplus / as sysdba
SQL> alter system set db_recovery_file_dest_size=3g scope=both; # 将闪回恢复区的大小设置为3G
系统已更改。
SQL> alter system set db_recovery_file_dest='/u01/app/oracle/flash_recovery_area' scope=both; # 指定闪回恢复区的位置
系统已更改。
3、设置闪回数据库的数据保留周期
SQL> alter system set db_flashback_retention_target=1440; # 周期为一天,以min为单位
系统已更改。
4、启用闪回日志
SQL> alter database flashback on;
数据库已更改。
SQL> alter database open;
数据库已更改。
SQL> show parameter db_recovery_file; # 查询是否成功启用闪回恢复区
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
db_recovery_file_dest string
/u01/app/oracle/flash_recovery
_area
db_recovery_file_dest_size big integer
3G
SQL> col TYPE for a15
SQL> col VALUE for a30
SQL> show parameter db_recovery_file;
NAME TYPE VALUE
------------------------------------ --------------- ------------------------------
db_recovery_file_dest string /u01/app/oracle/flash_recovery
_area
db_recovery_file_dest_size big integer 3G
SQL> col VALUE for a50
SQL> show parameter db_recovery_file;
NAME TYPE VALUE
------------------------------------ --------------- ------------------------------
db_recovery_file_dest string /u01/app/oracle/flash_recovery
_area
db_recovery_file_dest_size big integer 3G
SQL> select flashback_on from v$database; # 查询是否成功启用闪回数据库
FLASHBACK_ON
------------------------------------------------------
YES
5、取消闪回恢复区
将db_recovery_file_dest参数设置为空,可以停用闪回恢复区。但是,如果已经启用闪回数据库,则不能取消闪回恢复区。所以,必须先禁用闪回数据库,才能取消闪回恢复区。
SQL> shutdown immediate; # 关闭数据库
SQL> startup mount; # 装载数据库
SQL> alter database flashback off; # 关闭数据库闪回
SQL> alter database open; # 打开数据库
SQL> alter system set db_recovery_file_dest=''; # 修改闪回参数
4、使用scn闪回数据库
闪回数据库能够使数据迅速回滚到以前的某个时间点或者某个SCN的状态,这对于数据库从逻辑错误中恢复特别有用,而且也是大多数发生逻辑损害时恢复数据库的最佳选择。
1、查询数据库系统当前的scn
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
1789789
2、改变数据库的当前状态,模拟创建表test1,并插入1条数据
SQL> create table test1(id number,name char(20));
表已创建。
SQL> insert into test1 values(1,'data');
已创建 1 行。
SQL> commit;
提交完成。
3、进行闪回数据库恢复,将数据库恢复到创建表之前的状态
SQL> select OLDEST_FLASHBACK_SCN from v$FLASHBACK_DATABASE_LOG;
OLDEST_FLASHBACK_SCN
--------------------
1787872
SQL> shutdown immediate
SQL> startup mount;
SQL> flashback database to scn 1787872; # 1787872为查询到的SCN
闪回完成。
4、使用resetlogs选项打开数据库
SQL> alter database open resetlogs;
数据库已更改。
5、验证数据库的状态
SQL> select * from test1;
select * from test1
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
6、按照指定时间闪回数据库
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; # 设置显示日期格式
会话已更改。
SQL> select sysdate from dual; # 查看系统时间
SYSDATE
-------------------
2020-05-22 15:17:53
SQL> set time on;
15:17:58 SQL> create table test2(id number,name char(20)); # 模拟创建表test2
表已创建。
15:18:09 SQL> insert into test2 values(1,'data'); # 插入1条记录
已创建 1 行。
15:18:15 SQL> commit;
提交完成。
15:18:33 SQL> shutdown immediate;
15:19:11 SQL> startup mount;
15:19:19 SQL> flashback database to timestamp to_timestamp('2020-05-22 15:17:53','yyyy-mm-dd hh24:mi:ss'); # 日期为前面查看到的系统时间
闪回完成。
15:19:44 SQL> alter database open resetlogs;
数据库已更改。
15:19:55 SQL> select * from test2;
select * from test2
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
说明:闪回数据库操作的限制
- 数据文件损坏或丢失等介质故障不能使用闪回数据库进行恢复。闪回数据库只能基于当前正常运行的数据文件。
- 闪回数据库功能启动后,如果发生数据库控制文件重建或利用备份恢复控制文件,则不能使用闪回数据库。
- 不能使用闪回数据库进行数据文件收缩操作。
- 不能使用闪回数据库将数据库恢复到闪回日志中可获得最早的SCN之前的SCNM,因为闪回日志文件在一定条件下被删除,而不是始终保存在闪回恢复区中。
5、使用SCN闪回表
闪回表是将表恢复到过去的某个时间点或者指定的SCN而不用恢复数据文件,为DBA提供了一种在线、快速、便捷的恢复方式,可以恢复对表进行的修改、删除、插入等错误的操作。利用闪回表技术恢复表中数据的过程,实际上是对表进行DML操作的过程。Oracle自动维护与表相关联的索引,触发器、约束等。
为了使用数据库闪回表功能,必须满足下列条件:
- 用户具有FLASHBACK ANY TABLE系统权限,或者具有所操作表的FLASHBACK对象权限。
- 用户具有所操作表的SELECT,INSERT,DELETE,ALTER对象权限。
- 启动被操作表的ROW MOVEMENT特性,可以采用下列方式进行。
- SYS用户或以AS SYSDBA身份登录的用户不能执行闪回表操作
1、授予用户权限
$ sqlplus / as sysdba
15:20:46 SQL> conn / as sysdba
已连接。
15:20:51 SQL> grant select any dictionary to c##scott; # 授予权限
授权成功。
15:20:56 SQL> set time on
15:21:02 SQL> conn c##scott/123456;
已连接。
15:21:07 SQL> select current_scn from v$database; # 查询SCN
CURRENT_SCN
-----------
1790449
15:21:14 SQL> update test3 set name='liu' where id=1;
已更新 1 行。
15:21:20 SQL> commit;
提交完成。
15:21:25 SQL> select * from test3;
ID NAME
---------- ------------------------------------------------------------
1 liu
2 zhao
3 wang
15:21:29 SQL> delete from test3 where id=3;
已删除 1 行。
15:21:35 SQL> commit;
提交完成。
15:21:47 SQL> select * from test3;
ID NAME
---------- ------------------------------------------------------------
1 liu
2 zhao
2、启动表的row movement特性
15:21:55 SQL> alter table test3 enable row movement;
表已更改。
15:22:03 SQL> flashback table test3 to timestamp to_timestamp('2020-05-22 15:21:35','yyyy-mm-dd hh24:mi:ss'); # 时间为之前提交的时间
闪回完成。
15:22:46 SQL> select * from test3; # 闪回到了删除前的表
ID NAME
---------- ------------------------------------------------------------
1 liu
2 zhao
3 wang
15:22:52 SQL> flashback table test3 to scn 1790449; # 闪回到了表格第一次commit的数据
闪回完成。
6、闪回删除
闪回删除可恢复使用DROP TABLE语句删除的表,是一种对意外删除的表的恢复机制。闪回删除功能的实现主要是通过Oracle数据库中的回收站(Recycle Bin)技术实现的。在Oracle数据库中,当执行DROPTABLE操作时,并不立即回收表及其关联对象的空间,而是将它们重命名后放入一个称为回收站的逻辑容器中保存,直到用户决定永久删除它们,或存储该表的表空间存储空间不足时,表才真正被删除。为了使用闪回删除技术,必须开启数据库的回收站。
不支持SYS用户,SYSTEM表空间下的对象也不能从回收站里拿到。故使用SYS或者SYSTEM用户登录时,查询为空
1、启动回收站
在默认情况下回收站已经启动
15:23:14 SQL> conn / as sysdba;
已连接。
15:23:24 SQL> show parameter recyclebin;
NAME TYPE VALUE
------------------------------------ --------------- ------------------------------
recyclebin string on
15:23:29 SQL> alter system set recyclebin=on deferred;
系统已更改。
2、查看回收站
15:23:34 SQL> conn c##scott/123456;
已连接。
15:23:40 SQL> create table test4(id number,name char(20));
表已创建。
15:23:46 SQL> insert into test4 values(3,'wang');
已创建 1 行。
15:23:51 SQL> commit;
提交完成。
15:23:56 SQL> drop table test4;
表已删除。
15:25:10 SQL> col ORIGINAL_NAME for a20
15:25:39 SQL> col OBJECT_NAME for a40
15:25:56 SQL> select object_name,original_name,type from user_recyclebin; # 查看回收站
OBJECT_NAME ORIGINAL_NAME TYPE
---------------------------------------- -------------------- ---------------
BIN$pjfmyORcD6HgUwEBqMCc3A==$0 PK_EMP INDEX
BIN$pjfmyORdD6HgUwEBqMCc3A==$0 EMP TABLE
BIN$pjfxCnKKEAXgUwEBqMCwSA==$0 PK_EMP INDEX
BIN$pjfxCnKLEAXgUwEBqMCwSA==$0 EMP TABLE
BIN$pjiDXz1kFwLgUwEBqMDJ1g==$0 TEST4 TABLE
15:25:58 SQL> flashback table test4 to before drop rename to new_test4; # 闪回表并重命名为new_test4
闪回完成。
15:26:10 SQL> select * from new_test4;
ID NAME
---------- ------------------------------------------------------------
3 wang
3、清除回收站
由于被删除表及其关联对象的信息保存在回收站中,其存储空间并没有释放,因此需要定期清空回收站,或清除回收站中没用的对象(表、索引、表空间),释放其所占用的磁盘空间。
清除回收站的语法格式如下:
PURGE [TABLE table | INDEX index] |
[RECYCLEBIN | DBA_RECYCLEBIN]
[TABLESPACE tablespace [USER user] ]
参数 | 说明 |
---|---|
TABLE | 从回收站中清除指定的表,并回收其磁盘空间 |
INDEX | 从回收站中清除指定的索引,并回收其磁盘空间 |
RECYCLEBIN | 清空用户回收站,并回收所有对象的磁盘空间 |
DBA_RECYCLEBIN | 清空整个数据库系统的回收站,只有具有SYSDBA权限的用户才可以使用 |
TABLESPACE | 清除回收站中指定的表空间,并回收磁盘空间 |
USER | 清除回收站中指定表空间中特定用户的对象,并回收磁盘空间 |
操作如下
SQL> purge table test4;
SQL> purge recyclebin; # 清空回收站,慎用
7、闪回查询
闪回查询即允许根据时间点或SCN查看旧的数据。除了可以查看旧数据,需要时还可以通过检索旧数据来撤销错误的更改。
闪回查询的基本语法格式如下:
SELECT column_name[,....]
FROM table_name
[AS OF SCNITIMESTAMP expression]
[WHERE condition]
参数说明如下。
- AS OF TIMESTAMP:基于时间的闪回查询。
- AS OF SCN:基于SCN的闪回查询。
15:26:27 SQL> conn c##scott/123456;
已连接。
15:26:33 SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
会话已更改。
15:26:38 SQL> set time on;
15:26:45 SQL> select empno,sal from emp where empno=7844;
EMPNO SAL
---------- ----------
7844 1500
15:26:51 SQL> update emp set sal=2000 where empno=7844;
已更新 1 行。
15:26:58 SQL> commit;
提交完成。
15:27:06 SQL> update emp set sal=2500 where empno=7844;
已更新 1 行。
15:27:12 SQL> update emp set sal=3000 where empno=7844;
已更新 1 行。
15:27:17 SQL> commit;
提交完成。
15:27:21 SQL> select empno,sal from scott.emp as of timestamp sysdate-1/24 where empno=7844; # 查询7844员工前一个小时的工资值
select empno,sal from scott.emp as of timestamp sysdate-1/24 where empno=7844
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
15:28:50 SQL> select sal from emp as of timestamp to_timestamp('2020-05-22 15:27:17','yyyy-mm-dd hh24:mi:ss') where empno=7844; # 查询第二次commit之前的数据
SAL
----------
2000
五、备份脚本
1、RMAN全备+增量备份
1、全增备份脚本
# vi rman_level_0.sh
#!/bin/bash
# 源入bash配置文件
source ~/.bash_profile
# 设置备份日期和路径变量
export BACKUP_DATE=$(date +%Y%m%d)
export BACKUP_PATH=/orabak/rman
# 如果目录不存在,则创建必要的目录
mkdir -p "${BACKUP_PATH}/${BACKUP_DATE}/backupset" || echo "创建备份集目录失败"
mkdir -p "${BACKUP_PATH}/${BACKUP_DATE}/archivelog" || echo "创建归档日志目录失败"
mkdir -p "${BACKUP_PATH}/${BACKUP_DATE}/controlfile" || echo "创建控制文件目录失败"
# 运行RMAN并进行错误检查
rman target / nocatalog msglog="${BACKUP_PATH}/${BACKUP_DATE}/bak_0_${BACKUP_DATE}.log" << EOF
run {
# 分配通道
allocate channel c1 type disk;
allocate channel c2 type disk;
allocate channel c3 type disk;
# 完整数据库备份(增量级别0)
backup incremental level 0 database tag='level_0' format '${BACKUP_PATH}/${BACKUP_DATE}/backupset/level_0_%d_%T_%s_%U';
# 归档当前日志
execute sql 'alter system archive log current';
# 备份自昨日午夜以来的归档日志
backup archivelog from time 'sysdate-1' until time 'sysdate' format '${BACKUP_PATH}/${BACKUP_DATE}/archivelog/arch_level_0_%d_%T_%s_%U';
# 备份当前控制文件
backup current controlfile tag='bak_ctlfile' format '${BACKUP_PATH}/${BACKUP_DATE}/controlfile/ctl_file_%U_%T';
# 释放通道
release channel c1;
release channel c2;
release channel c3;
# 执行维护任务
crosscheck backup; # 核对备份信息
delete noprompt expired backup; # 删除已过期的备份
crosscheck archivelog all; # 核对所有归档日志
delete noprompt obsolete; # 删除废弃的备份片段
delete noprompt archivelog all completed before sysdate-7; # 删除7天前已完成的归档日志
}
exit
EOF
# 检查RMAN命令执行完毕后的返回码,如果非零则输出错误信息
if [ $? -ne 0 ]; then
echo "RMAN备份过程出现错误。"
fi
2、增量备份脚本
# vi rman_level_1.sh
#!/bin/bash
# 源入bash配置文件
source ~/.bash_profile
# 设置备份日期变量,格式为年月日
export BACKUP_DATE=$(date +%Y%m%d)
# 设置备份路径变量
export BACKUP_PATH=/orabak/rman
# 输出当前时间,格式为年月日 时-分-秒
echo $(date "+%Y%m%d %H-%M-%S")
# 创建备份目录结构(如果不存在)
mkdir -p "${BACKUP_PATH}/${BACKUP_DATE}/backupset" || echo "创建备份集目录失败"
mkdir -p "${BACKUP_PATH}/${BACKUP_DATE}/archivelog" || echo "创建归档日志目录失败"
mkdir -p "${BACKUP_PATH}/${BACKUP_DATE}/controlfile" || echo "创建控制文件目录失败"
# 执行RMAN命令并输出到指定日志文件
rman target / nocatalog msglog="${BACKUP_PATH}/${BACKUP_DATE}/bak_1_${BACKUP_DATE}.log" << EOF
run {
# 分配三个磁盘通道用于备份
allocate channel c1 type disk;
allocate channel c2 type disk;
allocate channel c3 type disk;
# 执行增量级别1的数据库备份,并打上'tag=level_1'标签
backup incremental level 1 database tag='level_1' format '${BACKUP_PATH}/${BACKUP_DATE}/backupset/level_1_%d_%T_%s_%U';
# 强制系统归档当前日志
execute sql 'alter system archive log current';
# 备份从昨天午夜开始到今天此刻的所有归档日志
backup archivelog from time 'sysdate-1' until time 'sysdate' format '${BACKUP_PATH}/${BACKUP_DATE}/archivelog/arch_level_0_%d_%T_%s_%U';
# 备份当前控制文件,并打上'tag=bak_ctlfile'标签
backup current controlfile tag='bak_ctlfile' format '${BACKUP_PATH}/${BACKUP_DATE}/controlfile/ctl_file_%U_%T';
# 释放已分配的备份通道
release channel c1;
release channel c2;
release channel c3;
# 核实备份信息
crosscheck backup;
# 删除过期的备份数据
delete noprompt expired backup;
# 核实所有归档日志
crosscheck archivelog all;
# 报告并删除废弃的备份片段
report obsolete;
delete noprompt obsolete;
# 删除7天前已完成的归档日志
DELETE noprompt ARCHIVELOG ALL COMPLETED BEFORE 'sysdate-7';
}
exit
EOF
# 检查RMAN命令执行结果,若返回码非零,则表示备份过程存在错误
if [ $? -ne 0 ]; then
echo "RMAN备份过程中出现错误。"
fi
创建定时任务
# crontab -e
# 在每周日(0代表周日)的凌晨00:30执行脚本
30 00 * * 0 rman_level_0.sh > /home/oracle/scripts/rman_level_0.log
# 在每周一至周六(1,2,3,4,5,6分别代表周一到周六)的凌晨00:00执行的脚本
0 0 * * 1,2,3,4,5,6 level1.sh > /home/oracle/scripts/rman_level_1.log
这两个cron任务分别负责在每周日进行一次全量(或接近全量)级别的RMAN备份,并在周一至周六进行增量级别1的RMAN备份
2、EXPDP备份
# mkdir /orabak/expdp
# chown -R oracle:oinstall /orabak/expdp/
# vim expdp.sh
#!/bin/bash
# 源入当前用户环境变量配置文件
source ~/.bash_profile
# 设置备份日期变量,格式为年月日
export BACKUP_DATE=$(date +%Y%m%d)
# 使用expdp工具进行全库导出,并添加详细注释
# '"/ as sysdba"' 表示以SYSDBA权限连接到数据库实例
# directory参数指定导出数据时使用的Oracle DIRECTORY对象的名称(需要提前创建并赋权)
# dumpfile参数指定导出的数据文件名,包含当前日期
# logfile参数指定导出过程的日志文件名,同样包含当前日期
# full=y表示执行全库导出操作
# COMPRESSION=ALL启用所有可能的压缩选项,以减少输出文件大小
# content=all表明导出内容包括表数据、表定义、索引等所有数据库对象
# FILESIZE限制单个数据文件的最大大小为20GB
expdp "'/ as sysdba'" directory=dir1 \
dumpfile=expdp_full_${BACKUP_DATE}.dmp \
logfile=expdp_full_${BACKUP_DATE}.log \
full=y \
COMPRESSION=ALL \
content=all \
FILESIZE=20000MB
if [ $? -eq 0 ]; then
echo "全库备份完成,备份文件:expdp_full_${BACKUP_DATE}.dmp 和 日志文件:expdp_full_${BACKUP_DATE}.log"
else
echo "全库备份失败,请查看 expdp_full_${BACKUP_DATE}.log 获取详细信息。"
fi
# crontab -e
30 02 * * * expdp.sh > /home/oracle/scripts/expdp.log
评论区