接上一篇【基础知识】RMAN基础知识-Part1
利用两篇将之前学的内容整理出来,又做了一遍实验,常用不常用的都有。有很多可以深挖的点,后面慢慢搞再
一、配置备份集-备份片-压缩-加密
1.配置备份集最大大小
configure maxsetsize to 500m;
configure maxsetsize clear;
如果备份大于设定数值,则备份的时候会提示不成功,一般来说 都不会设置备份集最大大小
2.配置备份片的最大大小
configure channel device type disk maxpiecesize 500m;
3.双工备份集(备份的时候会产生两个一模一样的备份集)很少用
configure datafile backup copies for device type disk to 2;
configure datafile backup copies for device type disk clear;
4.备份整个数据库时可以排除部分表空间
configure exclude for tablespace sysaux;
--下面这样备份不会受配置影响,假设已经配置不备份sysaux表空间,但是使用这条语句备份的话,就不受配置影响
backup database noexclude;
5.配置压缩
RMAN支持备份集的预压缩处理和二进制压缩
预压缩块处理:通过合并每个数据块中的空闲空间并将改空闲空间设置为二进制0来实现更好的备份压缩
--启用压缩
configure device type disk backup type to compressed backupset;
--设置压缩级别,选择high备份时CPU占用高
configure compression algorithm 'BASIC|HIGH|MEDIUM|LOW'
二、配置备份加密
- 口令加密模式
- 透明加密模式(wallet钱包)
- 混合
加密算法可以通过v$rman_encryption_algorithms视图查看,默认AES128。
RMAN加密CPU密集型操作,可能会对备份性能影响。
1.口令加密模式
--开启设置,设置口令为oracle
set encryption on identified by "oracle" only;
--备份数据文件 4号
backup datafile 4;
--在没有解密的情况下,尝试恢复会报错
--使用口令解密
set decryption identified by "oracle";
--恢复数据文件4
restore datafile 4;
recover datafile 4;
alter database open;
--可以把备份集拿到异机恢复,只要密码指定正确就可以。
2.透明加密模式 wallet
在备份的时候可以自动加密,在restore的时候可以自动解密
- 创建wallet目录
mkdir -p /u01/app/oracle/admin/prod/wallet
- 设置秘钥
alter system set encryption key identified by "oracle";
- 打开与关闭wallet
--关闭钱包:
alter system set wallet close identified by "oracle";
--打开钱包:
alter system set wallet open identified by "oracle";
4.其他
--打开加密
configure encryption for database on;
这种备份在本机还原时,无须输入密码,wallet自动解密,加密。
把备份集复制到其他机器,无法恢复。
3.混合模式
既可以在本机恢复,也可以在异机恢复(很少用,没做实验)
--单纯口令模式后面会有only,这里去掉
set encryption on identified by "oracle";
set decryption identified by "oracle";
--把钱包打开
alter system set wallet open identified by "oracle";
三、执行数据库恢复
前提:1.数据库必须是归档模式;2.有RMAN备份
恢复情形1
如何在丢失一个或多个数据文件后使用RMAN使数据库恢复正常运行。
场景:
- 删除undo,system,users表空间对应数据文件
- 不考虑控制文件、redo文件、参数文件、临时文件
恢复步骤:
--关闭数据库,文件都已经删除了用immediate肯定是不行
shutdown abort
--启动到mount状态,备份信息是存在控制文件中
startup mount
--查看实例状态
select status from v$instance;
--登陆RMAN,执行restore恢复删掉的物理文件
restore database;
restore datafile '/xxxx/xx/dbf'
restore datafile 1;
--整体恢复,应用日志
recover database;
recover datafile xxx;
--打开数据库
alter database open;
--如果用run块
RMAN>run{
restore database;
recover database;
}
SQL>alter database open;
--如果数据文件的原始位置空间满,恢复不想恢复到这个位置
--原位置:/u01/app/oracle/oradata/prod
--新位置:/u01/app/oracle/oradata/prod2
--使用set newname改变控制文件中的信息
run{
set newname for datafile 1 to '/u01/app/oracle/oradata/prod2/system01.dbf';
set newname for datafile 2 to '/u01/app/oracle/oradata/prod2/sysaux01.dbf';
set newname for datafile 3 to '/u01/app/oracle/oradata/prod2/undotos01.dbf';
set newname for datafile 4 to '/u01/app/oracle/oradata/prod2/users01.dbf';
restore database;
switch datafile all; --让控制文件里的信息改变过来
recover database;
}
alter database open;
恢复情形2
误删除了某个表的数据,要求恢复到删除数据前的某个时间点
--关闭数据库启动到mount状态
shutdown immediate
startup mount
--rman下执行
run{
set until time "to_date('2021-01-19 12:55:21','yyyy-mm-dd hh24:mi:s')";
restore database;
recover database;
}
alter database open resetlogs; --数据库做了不完全恢复都需要用resetlogs恢复
注意:使用resetlogs打开的数据库之后,数据库就开启了新的分支,之前的备份不能用于新的分支上进行恢复,需要重新备份。
四、使用DataRecoveryAdvisor恢复数据库
恢复指导,是一款oracle数据库工具,自动故障诊断,提供适当的恢复建议
RMAN> list failure; --需要触发才有信息
RMAN> advise failure;
RMAN> repair failure preview; --查看恢复脚本内容
RMAN> repair failure;
五、使用块跟踪加速备份
Block Change Tracking块跟踪,打开块跟踪是做增量备份的基础,主要用在RMAN的增量备份,记录自上一次备份以来数据库的变化,标识更改的块进行增量备份,CTWR(change tracking writer)进程 ,启用后就能看到这个后台进程。只读取改变的内容,不需要对整个数据库进行扫描,从而提高RMAN的备份性能。加快备份,缩短备份时间。
--查询
select * from v$block_change_tracking;
--创建记录改变的文件
alter database enable block change tracking using file '/u01/ctf';
alter database disable block change tracking;
--db_create_file_dest 如果设置了这个值 就不需要再输入 using file ‘XX’
六、增量备份
- 差异增量备份
- 累积增量备份
- 增量更新备份(oracle特有)
1.差异增量备份
自上一次同级别的差异备份或者是上一次更高级别的备份完成之后的数据库发生改变的数据块
说明:通俗些 其0级备份是对数据空间的完整备份(包括数据库逻辑日志),其备份量较大,在此基础上的1级备份,是增量备份,备份量较小,只备份0级备份之后的数据。
0级备份是全备 1级备份是增量备份
注意:
backup database: --整库备份,不能作为增量策略的一部分
backup incremental level 0 database; --整库备份,可以作为增量备份的基础。
--0级备份
backup incremental level 0 database format '/u01/backup/l0_%U'
--1级增量备份
backup incremental level 1 database format '/u01/backup/l1_%U'
2.累积增量备份
自上一次上0级备份完成以来数据库所有的改变信息。
--累积增量备份多了关键字cumulative
backup incremental level 1 cumulative database format '/u01/backup/lc1_%U';
注意:差异增量备份跟累积增量备份不要混用,只用一种就行,通常差异增量备份用得多
七、基于增量备份的数据恢复
--周六:0级备份(scn 716049)
backup incremental level 0 format '/u01/backup/full_%U' datatbase;
--周日-周五:1级差异增量备份
--备份第一次(scn 716120):
backup incremental level 1 format '/u01/backup/level1_%U' database;
--备份第二次(scn 716148):
backup incremental level 1 format '/u01/backup/level1_%U' database;
--查询数据库文件当前scn
select file#,name,CHECKPOINT_CHANGE# from v$datafile_header;
--restore完毕scn是716049,recover 第一个增量是716120,第二个就变成716148
--如果日志文件中包含了增量备份集的scn,那么就会直接应用日志文件
--注意看v$log视图中的first_change#,next_change#,代表日志开始的scn跟结束的scn,如果增量备的scn在 这个范围内就不会应用
总结:
- 首先就是restore database恢复文件从0级备份中恢复文件
- recover应用增量备份,归档日志,redo日志
- 全部都是自动完成,在rman命令下
八、使用Catalog恢复目录管理备份信息
catalog恢复目录就是一个Oracle数据库,用来存储Oracle数据库的备份信息,一个或者多个。
单个数据库是用控制文件来存储备份信息,控制文件存储备份信息保存時間有限
control_file_record_keep_time 默认7天/生产环境一般设置为30天
rman target /
rman target / nocatalog
--使用这两种方式登录就是用控制文件存储备份信息
--rman登录后会提示,using target database control file instead of recovery catalog
catalog数据库的dbid必须与备份的数据库dbid不一样
--查看dbid
select dbid from v$database;
步骤:
--1.创建恢复目录使用的用户
create user rco identified by rco quota unlimited on users; --quota unlimited 用户在表空间所分配的空间没有限制
grant connect,resource,recovery_catalog_owner to rco;
--2.创建恢复目录,在源库rman连接恢复目录
rman target / catalog rco/rco@192.168.230.101:1521/prod
create catalog;
--3.在恢复目录中注册数据库
--执行完成后会将控制文件中的备份信息同步到catalog库
register database;
--手工同步
--场景:已经在恢复目录中注册数据库,又使用nocatalog模式登录进行了备份,这种情况下在catalog库中是没有备份信息的,需要登录到catalog库中,手工执行resync catalog进行同步;
resync catalog;
九、制造坏块
1.创建一个用户,创建表,插入数据,执行以下存储过程插入数据
create table test (name varchar2(50));
begin
for i in 1..5000 loop
insert into test(name) values('pxk');
end loop;
commit;
end;
/
2.确认数据存储在哪些块
现在需要知道这些数据存在哪一个块,破坏掉,oracle提供了一个包,执行下面的查询:
--rowid_object用于取得特定ROWID所对应的数据对象号
select name,dbms_rowid.rowid_object(rowid) from test;
--查询每一行数据对应rowid
select rowid,name from test;
rowid的组成分为四个部分(16进制):
AAASppAAEAAAACDAAA
AAASpp-AAE-AAAACD-AAA
- 前六个字符是对象ID
- 中间三个是文件ID
- 下面六个是块ID
- 最后三位是行号
--查询对象ID,文件ID,块ID,行号
select distinct dbms_rowid.rowid_object(rowid) as objectid,dbms_rowid.rowid_relative_fno(rowid) as file_nu,dbms_rowid.rowid_block_number(rowid) as blockId,dbms_rowid.rowid_row_number(rowid) from test;
根据object_id到dba_objects表查询:
--确认对象为test表
select object_name,object_type from dba_objects where object_id='87387';
查询文件ID:
--查询可见该表在system表空间的数据文件中
select file# from v$dbfile where file#=1;
3.创建坏块
提取块:
--使用dd命令破坏,先提取一个块
dd if=/oradata/datafile/pxk/system01.dbf of=test.dbf bs=8192 count=1 skip=94625 conv=notrunc
写入破坏:
dd if=/dev/zero of=/oradata/datafile/pxk/system01.dbf bs=8192 count=1 seek=94625 conv=notrunc
完成这一步,test表所在的块就用全0破坏掉了,这时候执行select 语句这个表就会有报错提示, 如果没有的话,用下面语句刷新
--刷新命令,把内存中的数据,刷到文件中去
alter system flush buffer_Cache;
报错信息:
4.检查坏块
方式1:
validate datafile 1;
--提示有1或多个坏块
查看提示信息中的trace文件,其中显示为94625号块,就是我们破坏的那个
方式2:
--使用oracle提供的dbv工具
dbv file=/oradata/datafile/pxk/system01.dbf
```# 标题
![image.png](https://oss-emcsprod-public.modb.pro/image/editor/20210403-73b53a8c-f0a3-4f03-b462-b3aaa42656d7.png)
**方式3**:
```sql
--使用视图查看坏块
select * from v$database_block_corruption
十、块屏蔽与块恢复
1.块恢复:
可以使用块恢复来恢复一个或者多个损坏文件块。
优点:
1.降低MTTR平均故障恢复时间,只需要恢复损坏的块。
2.恢复期间,数据文件依然是联机的状态。
3.如果没有块恢复技术,单个块坏掉,也需要整个数据文件离线,恢复,online。这样恢复时间就很长,影响业务运行。
前提条件:
必须得有RMAN备份
恢复语句:
--少量坏块恢复
恢复语句:recover datafile 1 block 94625;
--大量坏块建议使用DRA数据局恢复指导
2.块屏蔽
没有备份的话,可以屏蔽坏块,其他块不影响。
--查询块屏蔽是否启用
select skip_corrupt from dba_tables where table_name='TEST'
--执行块屏蔽
exec dbms_repair.skip_corrupt_blocks('SYS','TEST');
--屏蔽后会发现select该表,发现可以查询,但是数据变少了,就是因为把坏块屏蔽掉了
十一、使用dbms_backup_restore包
使用场景:
- 只有备份集(包含控制文件和数据文件)
- 数据文件与控制文件都被删除掉
如果使用rman,需要先恢复控制文件,能够启动到mount状态,在恢复数据文件
如果通过这个包呢,在nomount状态下就能恢复控制文件跟数据文件,比rman方便
1.nomount下恢复控制文件
--执行下面存储过程,完成后发现控制文件已经恢复
declare
deviceType varchar2(256);
done boolean;
begin
devicetype:=dbms_backup_restore.deviceAllocate(type=>'',ident=>'t1'); --t1可换成任意字符
dbms_backup_restore.restoresetDataFile;
dbms_backup_restore.restoreControlFileto('/oradata/datafile/pxk/control01.ctl');
dbms_backup_restore.restoreBackupPiece('/u01/app/oracle/product/11.2.0/db_1/dbs/c-1967227408-20210403-00',done=>done); --这里要指明备份片的位置
dbms_backup_restore.deviceDeallocate;
end;
/
2.nomount下恢复数据文件
declare
deviceType varchar2(256);
done boolean;
begin
devicetype:=dbms_backup_restore.deviceAllocate(type=>'',ident=>'t1');
dbms_backup_restore.restoresetDataFile;
dbms_backup_restore.restoreDataFileto(dfnumber=>1,toname=>'/oradata/datafile/pxk/system01.dbf');
dbms_backup_restore.restoreDataFileto(dfnumber=>2,toname=>'/oradata/datafile/pxk/sysaux01.dbf');
dbms_backup_restore.restoreDataFileto(dfnumber=>3,toname=>'/oradata/datafile/pxk/undotbs01.dbf');
dbms_backup_restore.restoreDataFileto(dfnumber=>4,toname=>'/oradata/datafile/pxk/users01.dbf');
dbms_backup_restore.restoreBackupPiece('/u01/app/oracle/product/11.2.0/db_1/dbs/12vrcvsl_1_1',done=>done);
dbms_backup_restore.deviceDeallocate;
end;
/
--上面执行完,再到rman下recover
--再到sqlplus下alter database open RESETLOGS;
dbms_backup_restore包的局限性:
- 恢复时必须了解备份片信息,是不是含有数据文件、控制文件等。
- 恢复数据库需要指明文件号,新的文件名要恢复到哪里去,数据文件备份集在哪个路径。
RMAN恢复控制文件,数据文件没有这些限制。
十二、使用RMAN进行表级别恢复
12c新特性,基于表的时间点恢复
delete在时间范围内可以闪回
DDL(drop,truncate)等误操作可以用rman表級別的恢复
恢复原理:
- 建立一个辅助的实例
- 在辅助实例上做全库的恢复
- 通过datapump工具导出,导入
recover table sys.test
until time "to_date('2018-05-20 15:53:29','yyyy-mm-dd hh24:mi:s')"
auxiliary destination '/u01/tsbak' --这是辅助实例的路径,提前创建好
remap table sys.test:sys.test_new --恢复的时候可以导航为其他表
datapump destination '/tmp' --指定dump文件的路径
dumpfile 'exp.dat' --dump文件的文件名
notableimport; --这个代表仅导出dump文件,但是不执行导入
在recover 的过程中会自动产生一个实例,通过ps -ef 能看到这个实例的后台进程
恢复完成后,该实例会自动删除,之前设定的目录下仅剩余一些残余文件
recover table sys.test
until time "to_date('2018-05-20 15:53:29','yyyy-mm-dd hh24:mi:s')"
auxiliary destination '/u01/tsbak' --这是辅助实例的路径
remap table sys.test:sys.test_new
十三、编写自动全量备份shell脚本
下面脚本仅仅用于学习,不适合生产
1.设置控制文件自动备份,设置备份位置
--修改参数:
show all;
--开启
CONFIGURE CONTROLFILE AUTOBACKUP ON;
--设置位置
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '/u01/backup/%d-ctrl-%F';
2.设置备份的脚本
--脚本后缀可以用 .RMN 文件: Oracle Recovery Manager Script
--脚本存放路径 : /u01/exec/fulldb.rmn
--保留7天,删除之前的备份
run{
allocate channel ch1 device type disk;
allocate channel ch2 device type disk;
delete noprompt backupset completed before 'sysdate-7'; --删除7天前的备份
sql 'alter system archive log current'; --该语句意思为归档当前的日志文件,目的为最大限度的备份数据库
backup format '/u01/backup/%d_full_%U' database; --%d当前数据库的名字
backup archivelog all format '/u01/archbak/%d_arch_%U' delete all input; --delete all input意思为删掉所有输入,因为归档备份完成后,归档日志就没用了,可以删掉腾出空间
release channel ch1;
release channel ch2;
}
执行上述脚本
--执行没有问题再编写shell脚本
rman target / cmdfile fulldb.rmn
3.编写shell脚本
--1.创建fulldb.sh
#!/bin/bash
echo "=====================">>/u01/backup/fulldb.log
echo "===================fulldb "`(date +"%Y-%m-%d")`"===========">>/u01/backup/fulldb.log
echo "================Full RMAN Backup Begin==============" >> /u01/backup/fulldb.log
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
export ORACLE_SID=pxk
export NLS_LANG=american_america.zhs16gbk
export NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:s'
/u01/app/oracle/product/11.2.0/db_1/bin/rman target / cmdfile /home/oracle/backup.rmn log /u01/backup/fulldb.log append
echo $(date +"%Y-%m-%d %H:%M:%S") >> /u01/backup/fulldb.log
echo "================Full RMAN Backup End==============" >> /u01/backup/fulldb.log
4.crontab定时任务
crontab -e
0 1 * * * /home/oracle/fulldb.sh > /dev/null 2&>1
crontab -l
每天凌晨1点执行脚本
1列—分钟
2列—小时
3列—日期
4列—月份
5列—星期
6列—命令
1–代表标准输出 2–代表标准错误
2&>1 代表2的输出重定向等同于1,无论标准输出还是标准错误都往里面丢
例子:aaaa 2>/dev/null 就不会在屏幕上输出错误
十四、编写自动增量备份shell脚本
1.设置0级备份
--/home/oracle/level0.rmn
--如果备份信息保留7天,那么就设置sysdate-14
--脚本内容:
run{
delete noprompt backupset completed before 'sysdate-14'; --删除旧备份
sql 'alter system archive log current'; --归档当前的redo log
backup incremental level 0 format '/u01/backup/%d_inc0_%U' database;
backup archivelog all format '/u01/archbak/%d_arch_%U' delete all input';
}
2.设置1级备份
--/home/oracle/level1.rmn
--脚本内容:
run{
delete noprompt backupset completed before 'sysdate-14';
sql 'alter system archive log current';
backup incremental level 1 format '/u01/backup/%d_inc1_%U' database; --差异增量备份
backup archivelog all format '/u01/archbak/%d_arch_%U' delete all input';
}
3.shell脚本
--/home/oracle/level0.sh
--脚本内容:
echo "--------------------Level 0 backup begin------------------------" >> /u01/backup/level0-1.log
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
export ORACLE_SID=pxk
export NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:s'
export NLS_LANG=american_america.zhs16gbk
/u01/app/oracle/product/11.2.0/db_1/bin/rman target / cmdfile /home/oracle/level0.rmn log /u01/backup/level0-1.log append
echo "--------------------level 0 end backup---------------------------" >> /u01/backup/level0-1.log
--/home/oracle/level1.sh
--脚本内容:
echo "--------------------Level 1 backup begin------------------------" >> /u01/backup/level0-1.log
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
export ORACLE_SID=pxk
export NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:s'
export NLS_LANG=american_america.zhs16gbk
/u01/app/oracle/product/11.2.0/db_1/bin/rman target / cmdfile /home/oracle/level1.rmn log /u01/backup/level0-1.log append
echo "--------------------level 1 end backup---------------------------" >> /u01/backup/level0-1.log
4.crontab设置
0 1 * * 0 /home/oracle/level0.sh > /dev/null 2&>1
--星期天凌晨1点执行0级备份
0 1 * * 1-6 /home/oracle/level1.sh > /dev/null 2&>1
--星期1-6凌晨1点执行1级备份
十五、补充
--注意备份顺序是数据文件、归档日志文件最后才是控制文件和参数文件
rman target / <<EOF
run{
allocate channel ch1 device type disk;
allocate channel ch2 device type disk;
sql 'alter system archive log current';
backup as compressed backupset database format '/u01/backup/rman/db_%d_%T_%U';
sql 'alter system archive log current';
backup current controlfile format '/u01/backup/rman/con_%s_%p';
crosscheck archivelog all;
release channel ch1;
release channel ch2;
}
EOF