热衷于分享各种干货知识,大家有想看或者想学的可以评论区留言,秉承着“开源知识来源于互联网,回归于互联网”的理念,分享一些日常工作中能用到或者频率比较的内容,希望大家能够喜欢,并提出宝贵地意见,我们一起提升,守住自己的饭碗。
一、背景
之前好多网友留言,想要深入了解Oracle rman物理备份。我大概梳理了一下相关知识。接下来,我们进入正题。
二、什么是RMAN?
RMAN 是一种用于集备份(backup)、还原(restore)和恢复(recover)数据库于一体的 Oracle 工具,它能够备份整个数据库、表空间、数据文件、控制文件、归档文件以及 Spfile 参数文件。
rman有两种备份方式:热备份和冷备份。
我们日常使用的备份方式就是热备份,但热备份的前提必须开启归档日志。即在数据库不停机持续提供服务的状态下进行数据库的备份。
还有一种是冷备份,在数据库处于装载模式时进行。控制文件必须装载,RMAN才能访问其库。关闭备份是一致的;数据文件是稳定的,关闭备份时数据库处于非归档日志模式下时唯一可用的备份类型。这种不建议大家使用。RMAN不支持以下文件备份:
1)口令文件
2)在线日志(redo)
3) 网络配置文件
4)告警文件(alert日志)、跟踪文件
/u01/app/oracle/diag/rdbms/orcl/orcl/trace
5)闪回日志
6)临时数据文件,临时表空间等
以上文件可以定期通过文件备份脚本进行备份。
三、RMAN体系结构
RMAN提供了一个备份资料库保存备份的详细信息,可以给出针对备份的各种报表,并且整合了相关的操作系统和SQL*Plus命令为rman命令,跨平台的RMAN命令既支持交互式调用,也支持脚本式调用,其目的是保护备份并且最大限度地降低备份和恢复操作中发生人为错误的可能性。RMAN是备份、恢复数据库的首选工具。
1、rman所在位置
[oracle@myoracle ~]$ echo $ORACLE_HOME/bin
2、目标数据库
目标数据库指想要备份、还原与恢复的数据库。
[oracle@myoracle ~]$ rman target /
[oracle@myoracle ~]$ rman target '"sys/oracle as sysdba"'
[oracle@myoracle ~]$ rman target '"sys/Systiger123@cdb19c as sysdba"'
3、服务器通道(进程)
通道简言之即是完成文件复制工作的的服务器进程,多通道则实现了并行执行操作,可以自动或手动分配通道, 一旦备份与还原操作启动,则 RMAN会根据配置启用一个或多个通道。
4、存储仓库
存储了与目标数据库及其备份相关的元数据,包含目标数据库物理结构的详细信息、数据文件的位置,已完成的所有备份的细节,RMAN 的永久配置信息,存储仓库始终被存储在目标数据库的控制文件内,或存储在恢复目录内(一个单独的 Oracle 数据库)
5、恢复目录catalog(DG\ADG)
可以将目标数据库的备份恢复,元数据等相关信息写入到一个单独的数据库,这个单独的数据库即为恢复目录,恢复目录可以存储 RMAN 脚本。
6、备份目的地
默认的备份目的地为闪回区,$ORACLE_BASE/fast_recovery_area/,可以设置参数 db_recovery_file_dest 参数和 db_recovery_file_size 进行调整。
RMAN>alter system set log_archive_dest_1='location=/home/oracle/archive'; #修改归档路径
SQL> alter system switch logfile; #切换归档日志
RMAN> backup datafile 1 format '/home/oracle/archive/%U'; #备份数据文件1
四、备份的工作机制
备份分为全量备份和增量备份,备份的前提必须要有全量备份,既0级备份。所谓增量备份,顾名思义即是每次备份仅操作那些发生了"变化"的数据块。
完整备份包含每个文件中每个使用过的块。增量备份只有自上一次备份以前改变的块。增量备份策略 必须从一个完整备份开始,之后可以有随意多次增量备份,但还原总是需要先还原完整备份(称为0 级备份),再应用增量备份,使文件保持最新。只有进行了新的0级备份,才能丢弃以前的备份。
五、FORMAT 字符串替代变量
注:如果在 BACKUP 命令中没有指定 FORMAT 选项,则 RMAN 默认使用%U为备份片段命名
使用 FORMAT 参数时可使用的各种替换变量,如下:
%c:备份片的拷贝数(从1开始编号);
%d:数据库名称;
%D:位于该月中的天数(DD);
%M:位于该年中的月份(MM);
%F:一个基于 DBID 唯一的名称,这个格式的形式为
c-IIIIIIIIII-YYYYMMDD-QQ,其中 IIIIIIIIII 为该数据库的 DBID,
YYYYMMDD 为日期,QQ 是一个1-256的序列;
%n:数据库名称,并且会在右侧用 x 字符进行填充,使其保持长度为8;
%u:是一个由备份集编号和建立时间压缩后组成的8字符名称。利用%u 可以为每个备份集生成一个唯一的名称;
%p:表示备份集中备份片段的编号,从1开始编号;
%U:是%u_%p_%c 的简写形式,利用它可以为每一个备份片段(即磁盘文件)生成一个唯一名称,这是最常用的命名方式;
%s:备份集的号;
%t:备份集时间戳;
%T:年月日格式(YYYYMMDD);
六、使用rman热备份
(一)全量备份
1、查看归档日志的位置
SQL> show parameter log_archive_dest_1;
2、使用RMAN备份归档日志
RMAN> backup format '/home/oracle/bak/arch_%T_%s_%U' archivelog all delete input; #在备份完成后,删除归档日志,如果是生产库,不建议直接操作此命令。
RMAN> list backup of archivelog all; #查看归档日志信息
3、使用RMAN进行数据级文件备份
(1)使用单个数据文件进行备份
查看文件信息
查询数据文件序号,备份数据文件,可根据数据文件序号指定备份的数据文件
SQL> col FILE_NAME for a50
SQL> select file_name,file_id from dba_data_files;
备份数据文件,可单个数据文件备份,即镜像备份,如backup as copy datafile 1 也可以将多个数据文件作为备份集进行备份:datafile 1,2,3,4
RMAN> backup as copy datafile 1 format '/home/oracle/bak/df1_%d_%U'; #数据文件备份
RMAN> backup tablespace USERS; #表空间备份
RMAN>backup current controlfile format='/home/oracle/bak/con%d_%s.ctl' #控制文件备份;RMAN> list copy; #查看备份信息

(2)使用备份集进行备份
RMAN> run{
allocate channel ch1 type disk
maxpiecesize=2g;
backup as compressed backupset
format '/home/oracle/bak/whole_%d_%U' filesperset=3
database;
release channel ch1;}

(3)删除备份
RMAN> delete backup;#删除所有备份
RMAN> delete noprompt backup;#不用确认删除所有备份,用在脚本里面,脚本里面没法输入YES
RMAN> delete archivelog all;#删除所有归档日志
RMAN> delete noprompt archivelog all;#不用确认删除所有归档日志
RMAN> delete noprompt archivelog until time 'sysdate-7';#删除7天前的归档
RMAN> delete obsolete; #删除陈旧备份;
RMAN> delete expired backup; #删除EXPIRED备份;
RMAN> delete expired copy; #删除EXPIRED副本;
RMAN> list backup of database; #列出所有备份信息
RMAN> crosscheck archivelog all; 核对所有归档
RMAN> crosscheck backup of database; #核对所有数据文件的备份集
(二)增量备份
RMAN> backup incremental level=0 database; #相当于全量备份,是增量备份基础
RMAN>backup incremental level=1 cumulative database; #累积的增量备份
(三) Oracle 19C热克隆
SQL> select con_id,name from v$datafile where con_id=2;
SQL> CREATE PLUGGABLE DATABASE pdb1 ADMIN USER pdb_mgr1 IDENTIFIED BY oracle roles=(dba) file_name_convert=('/u01/app/oracle/oradata/CDB19C/pdbseed','/u01/app/oracle/oradata/CDB19C/pdb1');
SQL> show pdbs;


七、 数据恢复
数据恢复需数据库需要处于MOUNT模式才能进行恢复。
在RMAN完全恢复中主要使用两个命令,一个是 restore ,另一个是 recover 。
可以在三个级别恢复,数据库,表空间,数据文件。
RMAN> backup datafile 'u01/app/oracle/oradata/CDB19C/system01.dbf' format '/home/oracle/bak/system_%U'; #完整备份
RMAN> backup incremental level 0 datafile '/u01/app/oracle/oradata/CDB19C/system01.dbf' format '/home/oracle/bak/system_0_%U'; #0级备份
backup incremental level 0 datafile '/u01/app/oracle/oradata/CDB19C/system01.dbf' format '/home/oracle/bak/system_1_%U'; #1级备份
模拟删除system01.dbf文件进行恢复
[oracle@myoracle rmanbackup]$ rm -rf /u01/app/oracle/oradata/CDB19C/system01.dbf
SQL> startup mount
RMAN> restore datafile '/u01/app/oracle/oradata/CDB19C/system01.dbf';
RMAN> recover datafile '/u01/app/oracle/oradata/CDB19C/system01.dbf';
八、备份脚本分享
此脚本为每周日进行全量备份,其余时间进行增量备份。
[oracle@myoracle backup]$chmod -R 755 bak.sh
[root@myoracle cron]#crontab -e
#添加以下内容,每天两点进行全量备份
00 02 * * * /home/oracle/backup/bak.sh >/dev/null 2>&1 &
[oracle@myoracle backup]$ cat bak.sh #此脚本为每周日进行全量备份,其余时间进行增量备份。
#!/bin/bash
# ---------------------------------------#
if[-f $HOME/.bash_profile ];then
. $HOME/.bash_profile
elif[-f $HOME/.profile ];then
. $HOME/.profile
fi
backtime=`date +"20%y%m%d%H%M%S"`
orabakdir=/home/oracle/backup/rmanbackup #备份目录
[[-e ${orabakdir}]]|| mkdir -p ${orabakdir}
chown oracle:oinstall ${orabakdir}
chmod 750 ${orabakdir}
##全量备份保留天数
fulday=1
##增量备份保留天数
incrday=6
##归档保留天数
arcday=7
##备份策略
rmanPolicy(){
rman target / log=${orabakdir}/level_policy_${backtime}.log<<EOF
run{
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF ${arcday} DAYS;
CONFIGURE CONTROLFILE AUTOBACKUP ON;
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '${orabakdir}/%F';
}
EOF
}
##全量备份
fulBak(){
rman target / log=${orabakdir}/level0_backup_${backtime}.log<<EOF
sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';
run {
# backup all database
allocate channel c1 type disk;
allocate channel c2 type disk;
allocate channel c3 type disk;
allocate channel c4 type disk;
backup as compressed backupset incremental level 0 format '${orabakdir}/full_level0_%d_%t_%s_%p_%t' database;
sql 'alter system archive log current';
# backup all archive logs
backup as compressed backupset format '${orabakdir}/full_level0_arc_%s_%p_%t_%t' archivelog all;
# delete obsolete files
report obsolete;
crosscheck backup;
crosscheck archivelog all;
delete noprompt obsolete;
delete noprompt expired backup;
delete noprompt expired archivelog all;
delete noprompt archivelog all completed before 'sysdate-${arcday}';
delete noprompt backup completed before 'sysdate-${arcday}';
# backup controlfile
backup format '${orabakdir}/full_level0_contrl_%u_%t' current controlfile;
# backup spfile
backup format '${orabakdir}/full_level0_spfile_%u_%t' spfile;
release channel c1;
release channel c2;
release channel c3;
release channel c4;
}
EOF
}
##增量备份
incrBak(){
rman target / log=${orabakdir}/level1_backup_${backtime}.log<<EOF
sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';
run {
# allocate channels
allocate channel c1 type disk;
allocate channel c2 type disk;
allocate channel c3 type disk;
allocate channel c4 type disk;
# backup incremental level 1
backup as compressed backupset incremental level 1 format '${orabakdir}/incr_level1_%d_%t_%s_%p_%t' database;
sql 'alter system archive log current';
# backup all archive logs
backup as compressed backupset format '${orabakdir}/incr_level1_arc_%s_%p_%t_%t' archivelog all;
# delete obsolete files
report obsolete;
crosscheck backup;
crosscheck archivelog all;
delete noprompt obsolete;
delete noprompt expired backup;
delete noprompt expired archivelog all;
delete noprompt archivelog all completed before 'sysdate-${arcday}';
delete noprompt backup completed before 'sysdate-${arcday}';
# backup controlfile
backup format '${orabakdir}/incr_level1_contrl_%u_%t' current controlfile;
# backup spfile
backup format '${orabakdir}/incr_level1_spfile_%u_%t' spfile;
release channel c1;
release channel c2;
release channel c3;
release channel c4;
}
EOF
}
rmanPolicy
# 全量备份每天运行一次
if[[ $(date +%u)-eq 7]];then
fulBak
else
incrBak
fi
# 删除过期日志
find ${orabakdir}-name 'level*.log'-mtime +${arcday}-exec rm -f {} \;
九、恢复脚本分享
[oracle@myoracle backup]$cat restore.sh #完全恢复,前提是数据库必须在mount状态下#!/bin/bash
# 加载环境变量
if [ -f $HOME/.bash_profile ]; then
. $HOME/.bash_profile
elif [ -f $HOME/.profile ]; then
. $HOME/.profile
fi
# 设置变量
backtime=$(date +"%Y%m%d%H%M%S")
orabakdir=/home/oracle/bak/rmanbackup # 备份目录
logfile="${orabakdir}/restore_${backtime}.log"
## 恢复策略
rmanRestore() {
rman target log="${logfile}" <<EOF
STARTUP MOUNT;
RESTORE DATABASE;
RECOVER DATABASE;
ALTER DATABASE OPEN;
EXIT;
EOF
}
## 执行恢复策略
rmanRestore
echo "恢复操作已完成,请查看日志文件 ${logfile} 以确认详细信息。"
SELECT sid,
serial#,
CONTEXT,
sofar,
totalwork,
round(sofar / totalwork * 100,
2) "% Complete"
FROM v$session_longops
WHERE opname LIKE 'RMAN:%'
AND opname NOT LIKE 'RMAN: aggregate%';
文中的概念来源于互联网,如有侵权,请联系我删除。
欢迎关注公众号:小周的数据库进阶之路,一起交流数据库、中间件和云计算等技术。如果觉得读完本文有收获,可以转发给其他朋友,大家一起学习进步!感兴趣的朋友可以加我微信,拉您进群与业界的大佬们一起交流学习。





