恢复控制文件避免使用resetlogs选项 (r10笔记第12天)
在搭建Data Guard的时候,我们可以直接从主库生成一个备库控制文件,或者拷贝一个备库的控制文件即可,后续的工作就交给Data Guard来自动恢复完成了,尤其是使用rman备份恢复的时候,使用recover database是一气呵成,我们无须理会其中更多的细节,当然实际上Oracle已经帮我们处理好了。
我们都知道控制文件的备份有两种方式,一种是镜像,一种是trace。镜像备份方式类似alter database backup controlfile to 'xxxxx'这样的形式,而trace备份则类似于alter database backup controlfile to trace这样的形式。
从不少实际的操作中,我发现镜像的恢复方式会带来不少的困扰,如果是一个新人来做控制文件的恢复,可能会栽入不少坑里。最后一番折腾可能会带来一种直观的感觉就是控制文件实在太重要了,如果要恢复,操作复杂度和不完全恢复差不多。而且最让人纠结的是,折腾一番之后,还要resetlogs的方式open数据库,我不喜欢这种恢复方式,明明完全恢复,为什么需要这么多的弯路。我们可能在rman中也设置了autobackup,在11g中其实是有隐含参数来控制延迟创建,默认是5分钟。可见控制文件还是给很多人带来了太多困扰。
那么怎么恢复控制文件比较好呢。怎么使得控制文件的恢复无需resetlogs呢。其实实现起来很简单。
我们先来看看纠结的镜像恢复方式。首先是备份。
sys@OCP11G> alter database backup controlfile to '/home/ora11g/ctl.bak' reuse;
Database altered.
[ora11g@jeanron100 ~]$ sqlplus / as sysdba
sys@OCP11G> select *from v$controlfile;
STATUS
-------
NAME
------------------------------------------------
IS_ BLOCK_SIZE FILE_SIZE_BLKS
--- ---------- --------------
/u01/app/ora11g/oradata/ocp11g/control01.ctl
NO 16384 614
/u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl
NO 16384 614
2 rows selected.
我们手工删除控制文件
[ora11g@jeanron100 ~]$ rm /u01/app/ora11g/oradata/ocp11g/control01.ctl
[ora11g@jeanron100 ~]$ rm /u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl
这个时候停库会报错,所以只能是abort方式的断电重启。
sys@OCP11G> shutdown immediate
ORA-00210: cannot open the specified control file
ORA-00202: control file: '/u01/app/ora11g/oradata/ocp11g/control01.ctl'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
sys@OCP11G> shutdown abort
ORACLE instance shut down.
然后重启启动到nomount
sys@OCP11G> startup nomount
然后开始还原控制文件。
[ora11g@jeanron100 ~]$ cp /home/ora11g/ctl.bak /u01/app/ora11g/oradata/ocp11g/control01.ctl
[ora11g@jeanron100 ~]$ cp /home/ora11g/ctl.bak /u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl
接着mount就没有问题了。
idle> alter database mount;
Database altered.
当然在启库的时候肯定会有下面的提示信息,需要设置为resetlogs模式。
idle> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
当然我们尝试resetlogs,结果还是会有一连串的ORA错误抛出来。而在尝试recover的时候会提示recover using backup controlfile
idle> recover database;
ORA-00283: recovery session canceled due to errors
ORA-01610: recovery using the BACKUP CONTROLFILE option must be done
这个时候会折腾几次,因为归档中的数据变化都应用完了,数据库不知道该从哪个redo中恢复,这个就给问题的解决铺下了障碍。我们需要带着一丝的运气逐个输入redo的路径,快则一次搞定,满则需要多轮验证。
idle> recover database using backup controlfile;
ORA-00279: change 1178971 generated at 09/04/2016 02:03:43 needed for thread 1
ORA-00289: suggestion : /u01/app/ora11g/flash_recovery_area/OCP11G/archivelog/2016_09_04/o1_mf_1_25_%u_.arc
ORA-00280: change 1178971 for thread 1 is in sequence #25
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
当然费了一番周折还是提示要resetlogs
idle> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
而改进的方式就是使用trace的方式,我们在这个基础上继续补充,就不需要resetlogs了。
因为已经恢复了控制文件,但是似乎控制文件的SCN已经比数据文件头部要旧了。不过整体来看,数据文件的信息没有变化,只有最后的SCN的部分有一些差别,那么我们就可以使用trace的方式来弥补。
idle> startup nomount
idle> CREATE CONTROLFILE REUSE DATABASE "OCP11G" NORESETLOGS ARCHIVELOG
2 MAXLOGFILES 16
3 MAXLOGMEMBERS 3
4 MAXDATAFILES 100
5 MAXINSTANCES 8
6 MAXLOGHISTORY 292
7 LOGFILE
8 GROUP 1 '/u01/app/ora11g/oradata/ocp11g/redo01.log' SIZE 50M BLOCKSIZE 512,
9 GROUP 2 '/u01/app/ora11g/oradata/ocp11g/redo02.log' SIZE 50M BLOCKSIZE 512,
10 GROUP 3 '/u01/app/ora11g/oradata/ocp11g/redo03.log' SIZE 50M BLOCKSIZE 512
11 -- STANDBY LOGFILE
12 DATAFILE
13 '/u01/app/ora11g/oradata/ocp11g/system01.dbf',
14 '/u01/app/ora11g/oradata/ocp11g/sysaux01.dbf',
15 '/u01/app/ora11g/oradata/ocp11g/undotbs01.dbf',
16 '/u01/app/ora11g/oradata/ocp11g/users01.dbf',
17 '/u01/app/ora11g/oradata/ocp11g/testdata01.dbf',
18 '/u01/app/ora11g/oradata/ocp11g/testdata02.dbf'
19 CHARACTER SET UTF8
20 ;
idle> recover database ;
Media recovery complete.
idle> alter database open;
Database altered.
这个过程中直接alter database open也没有问题,问题引刃而解。
这个修复的过程让我想起来MySQL中的GTID,就是一个全局的标记位。使得搭建slave的时候更加省心,大多数情况其实我们也不需要知道更细节的 SCN,交给MySQL自己去判断就好。对于Oracle的恢复来说也是如此,我们可以借助Oracle提供的完善的后台服务来完成这个恢复工作,而无需 使用resetlogs,何乐而不为。
- Highway Networks
- CTF---编程入门第一题 循环
- Z.ExtensionMethods 一个强大的开源扩展库
- 【干货】神经网络SRU
- AutoMapper 使用实践
- CTF---安全杂项入门第二题 A记录
- PyTorch(总)---PyTorch遇到令人迷人的BUG与记录
- 手把手带你进入TOP20的商超销售预测
- 【干货荟萃】机器学习&深度学习知识资料大全集(二)(论文/教程/代码/书籍/数据/课程等)
- 逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能
- 【专知-Java Deeplearning4j深度学习教程06】用卷积神经网络CNN进行图像分类
- 万恶的剪贴板==》为存储而生
- AdaBoost算法(R语言)
- CTF---Web入门第六题 因缺思汀的绕过
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android:8.0中未知来源安装权限变更
- Android:RippleDrawable 水波纹/涟漪效果
- Android:Chip、ChipGroups、ChipDrawable
- Android9.0 使用 AndroidVideoCache 时不能缓存/播放视频的解决
- Android:流式布局实现总结
- 跨域问题汇总
- 优化 Docker 镜像大小常见方法
- 第10期:选择合适的表空间
- 在 Kubernetes 上编排 MongoDB 集群
- k8s技术圈一周精选[第7期]
- TypeScript namespace 命名空间
- 从Pytorch 的ONNX到OpenVINO中IR中间层
- Linux CPU 性能优化指南
- 差分隐私(Differential Privacy)
- ubuntu changelog/source获取方法