control file 中包含以下内容:
- database name
- time stamp of database creation
- Synchronization information(checkpoint and log sequence information) needed for recovery
- Names and locations of datafiles and redo log files
- Archiving mode of the database
- Current log sequence number
- Recovery Manager backup meta data(RMAN)
rman 的信息是由 oracle 系统自动更新的.
数据库要想打开, datafile, redo log, control file 必须同步.
打开 rman 的前提条件是 数据库处于 mount 或 open 状态, 那么如果control file 损坏, 数据库将不能 mount 或 open, 所以就无法使用 rman. 所以, control file 损坏, 只能使用以下的手动方法来处理.
Resetlogs
The resetlogs option is always required after incomplete media recovery or recovery using a backup control file.
- Archives the current online redo logs(if they are accessible) and then erases the contents of the online redo logs and resets the log sequence number to 1.
- Creates the online redo log files if they do not currently exist.
- Reinitializes the control file metadata about online redo logs and redo threads.
- Updates all current datafiles and online redo logs and all subsequent archived redo logs with a new resetlogs scn and time stamp.
以下内容, 为转载+总结, 很好
控制文件的恢复与重建, 是很困难的.
通常在当前控制文件丢失,或者当前的控制文件与需要恢复的控制文件不一致的情况下,我们需要重新创建一个控制文件或者使用 unsing
backup controlfile方式来恢复控制文件。说简单点,只要是备份的控制文件与当前的控制文件不一致进行恢复数据库,就需要使用到 unsing
backup controlfile方式,而一旦使用了该方式,则需使用resetlgos选项来打开数据库
所以控制文件是很麻烦的, 控制文件的恢复, 只有两种办法:
1. 通过以前备份过的控制文件来恢复, using backup controlfile
2. 重建控制文件, alter database backup controlfile to trace as ‘/u01/backup_controlfile/recreate_control.txt’
要注意, 对控制文件操作之前, 一定要先对数据库进行一次全备.
1. 恢复控制文件, using backup controlfile
先将数据库设置成 mount 状态.
ls –hltr /u01/oradata/ora10g/ 查询 control 的时间.
数据库mount以后, 控制文件的时间会更新为最新时间.
查看instance状态, select instance_name, status, database_status from v$instance;
确认当前controlfile状态: 可以看到, 当前controlfile 状态是 current, open_resetlogs 为 not allow.
此时, 假如我们control file 丢失了, 我们使用以前的 backup controlfile 来恢复
recover database using backup controlfile; -- 注意这里并不需要提供 backup controlfile 的路径.
输入完上边命令后, 出现如下提示:
它建议我们使用 /u01/oradata/ora10g/archivelog/arch_1_17_831209795.arc 来进行恢复, 但是, 我们实际去该目录去查看, 并没有看到该文件. 此时我们输入 cancel, 会显示 recover…, 然后我们查看 control file 的状态.
可以看到, 此时 control file 的状态已经从 current 变成了 backup, open_resetlogs 也从 not allowd 变成了 required.
此时, 我们尝试着打开数据库, alter database open; 注意一定要使用 alter database open resetlogs;
这时, 我们查看上边 recover 给出的提示:
suggested : 这条不行, 我们查看了该文件的目录, 里边没有这个suggest 文件.
cancel :也不行, 我们做过实验, 无法打开数据库.
auto : 没试过, 估计没戏
filename: 最后一条了, 此时我们可以指定 redo log file, 首先查询当前是执行的那个 redo log file,
可以看到, 当前是 redo01.log 正在执行, 我们就用这个文件作为 filename 再次运行 recover database using backup controlfile
注意: 我们直接输入 /u01/oradata/ora10g/redo01.log -- 没有引号
系统显示 log applied, Media recovery complete.
这时候, 我们尝试 open database. alter database open resetlogs;
此时可以看到, database open 成功了, 并且 controlfile 的状态也变成了 current了, 此时如果你查看系统上 control file的时间, 也同步到当前时间了.
查看 archivelog list , 看到没, 所有的号码变成了1, 这是一个incarnation, 下面有具体的 incarnation的解释.
总结(转载)
1、using backup controlfile用于恢复备份的控制文件与当前的控制文件不一致的情形
2、一旦使用了using backup controlfile方式,控制文件的类型将由 current 转移到 backup 类型,同时open_resetlogs为required
3、一旦使用了using backup controlfile方式,后续再次使用recover database将变得无效
4、必须要使用 resetlogs 方式打开数据库,即使我们做的是完全恢复
5、注意理解演示中时间状态的更新情况。实际上来说是实例的启动过程,即:
nomount: 根据pfile 或 spfile 启动相关后台进程,分配SGA
mount: 打开控制文件,检查控制文件状态一致性,将数据库与实例关联起来
open: 根据控制文件中记录的数据文件日志文件对其进行逐一检查无误后,整个数据库置于open状态
2. 重建控制文件
有些情况, 你必须重建控制文件, 例如数据库的名字变更, 等等.
首先要得到重建控制文件的脚本
1. alter database backup controlfile to trace as ‘/u01/user_controlfile/recreate_control.txt; 得到重建controlfile 脚本
2. 整理这个脚本
当我们将控制文件备份到trace 文件时,可以看到里面包含了2部分的重建语句,一个是使用resetlogs,另一个是使用noresetlogs
使用 noresetlogs 仅是当前所有的 online logs 可用时, 也就是说, 如果online redo logs 不可用, 那么就必须使用 resetlogs.
使用 resetlogs, 将导致 online redo logs 里的内容丢失, 并且所有的备份失效, 仅当 online redo logs 损坏的情况下, 使用 resetlogs 模式.
另外, 在数据库打开时
use RESETLOGS after incomplete recovery (when the entire redo stream was not applied), RESETLOGS will initialize the logs, reset your log sequence number, and start a new “incarnation” of the database. RESETLOGS 会初始化 log sequence 号, 创建一个新的 incarnation.
补充, incarnation:
incarnation: 英文翻译是化身, 在oracle 中可以叫做数据库的一个实体, 它指的是一个重置scn后的数据库的场景. 一个数据库在刚开始被创建出来, scn 号为1, 随着运行, scn 不断单调递增, oracle 就是根据scn 描述数据库的整个发展过程, 可以说scn就是数据库的时间轴, 当数据库正常运行, 或者执行完全恢复时, scn只会单调递增直到最新的scn, 这样数据库中所有的数据都按照时间的顺序改变着, 但如果数据库出现了人为误操作, 需要执行不完全恢复, 这时候就的用以前备份的所有数据文件将数据版本回到以前, 然后从那个起点开始应用日志, 直到出现人为故障之前的那一刻, 但这时, scn并未达到最新的scn, 而是得到了之前的某个scn, 在这一刻,人为故障还未发生。在完成recover .. until .. 的操作后,所有的数据文件通过应用日志到了统一的一点,但数据库暂时还不能正常打开,因为控制文件中记录的是最新的scn,与应用日志后的数据文件并不一致,因此无法直接打开数据库回到原始的状态,必须通过resetlogs的方式强制控制文件、重做日志文件以及数据文件的scn一致,此时新打开的数据库中第一个scn等于应用日志到的最后一条日志的scn号+1(在告警日志文件中可以看到RESETLOGS after incomplete recovery UNTIL CHANGE 145936 这样的信息,打开数据库后的scn则为145937)。数据库每次resetlogs之后,scn和日志序列号都被重置,因此每次resetlogs都会产生一个新的incarnation,而incarnation的信息存储在控制文件中,在rman中可以通过list incarnation看到实体信息。
可以通过 rman 将数据库恢复到某一个 incarnation, 后续再介绍
既然已经直到了 resetlogs 和 noresetlogs 的区别, 那么就分别进行测试:
1. 测试 noresetlogs :
整理脚本: (linux 命令)
去除空白行和注释行: grep –v ^- - /u01/user_controlfile/re_noresetlogs.txt | grep –v ^$ >/u01/user_controlfile/re_noresetlogs.txt
这是整理之后的脚本, 直接使用这个脚本就可以了
首先登陆 sqlplus /nolog, conn /as sysdba
@/u01/user_controlfile/no.txt
注意: 因为数据库中包含了 offline 和 read only tablespace, 这个是要在创建 control file 特殊处理的. 从 dba_tablespaces 和 dba_data_files 视图, 我们可以看出:
2. 测试 resetlogs :
同样, 整理脚本: (linux 命令)
去除空白行和注释行: grep –v ^- - /u01/user_controlfile/re_noresetlogs.txt | grep –v ^$ >/u01/user_controlfile/re_noresetlogs.txt
这两份脚本, 基本相同, 只是上边的第2行命令变成了 RESETLOGS, 另外有一点, 关键的一点要注意
之前的脚本命令式 recover database
后面的脚本命令 recover database using backup controlfile
@/u01/user_controlfile/yes.txt
出现了这些内容 :
首先查看了 arch_1_2_842279302.arc 这个文件是不存在的, 所以不能使用这个suggest 文件来恢复了.
使用一个 redo log 日志文件, 就恢复成功了.
首先在脚本的第一行添加 set echo on, 来确认脚本每个内容的结果
可以看到 control file created. 到这时, 没有问题
recover database using backup controlfile 出现了问题. 注意脚本中后面的操作的基础, 就是这一步, 这一步不成功直接导致后边失败. 但是目前, 我们control file 已经创建完成了.
跟之前一样, 上边的 recover database using backup controlfile 时也是使用一个 redo log file 就可以成功.
另外, 如果 controlfile 和 online redo log file 都丢失了, 并且最新的 online redo log file 没有归档, 也没有多路, 那么数据库只能做不完全恢复了.
恢复的办法是:
首先备份当前所有的数据库文件.
然后将原来的一个全备copy 到目前数据库的目录,( 这里假设之前的全备的control file也丢失了)
此时可以使用 create control file 的脚本重建 controlfile ( 注意这里是 resetlogs 模式 )
创建完新的 controlfile 之后, recover database using backup controlfile;
此时会提示你, 这个时候你会发现, 如果你保存了之前的全部archivelog是多么有用, 按照提示的archivelog 进行恢复. 这样, 系统就可以恢复到你这个archivelog归档的所有内容, 但是至于最新的redo log 的内容, 就丢失了, 需要让用户重做.
解决办法:
1. 你有多路复用的 control file, 这种基本上相当于没丢
2. create controlfile 命令创建一个新的control file, 这种要求你知道所有的file关于database的细节. (alter database backup controlfile to trace as ‘/u01/user_backup/ctl.txt’, 保存成这个文件格式, 便于我们查看.)
3. 使用之前备份的 control file 来恢复, alter database backup controlfile to ‘/u01/user_backup/controlfile_back.bak’;
问题1: 版本不一致
(假如 control01 的版本高于另外两个, 则参考如下办法:)
这种只是建立在多路复用的前提下, 控制文件并没有丢失, 只是多路之间的控制文件版本不同, 只要用高版本替换低版本的就可以了, 简单
办法: cp /u01/oracle/oradata/ora10g/control01.ctl cp /u01/oracle/oradata/ora10g/control02.ctl
cp /u01/oracle/oradata/ora10g/control01.ctl cp /u01/oracle/oradata/ora10g/control03.ctl
问题2: 部分控制文件丢失
这种也是建立在多路复用的前提下, 少部分复用的控制文件丢失, 也只是需要copy 一份其他的控制文件粘贴到相应路径, 并改成正确的文件名就可以了. 简单
将存在的控制文件复制到目的路径并更改控制文件名字为正确的控制文件名称
问题3: 非归档模式下, 所有 control file 丢失, 重建control file
考虑以下因素:
- 搞清各个日志文件的大小和位置
- 搞清各个数据文件的位置
- 设置正确的字符集
上边的转载, 有具体的重建control file 的详细内容
control file 真的要小心, 问题很严重, 因为control file 是动态变化的, 如果不是自动备份, 那么当所有的 control file 都丢失了, 那么就要进行 不完整恢复了, 因为如果你用之前的 control file, 那么 control file 里边的内容, 比如 SCN 等内容必然跟现在不一样, 所以还是设置自动备份 control file 和进行多路复用, 一定要保住 control file.
不完整恢复
Reasons for Performing Incomplete Recovery : (不完整恢复的原因)
- Complete recovery fails because an archived log is lost.
- All control files are lost. (哇, 如果所有的控制文件丢失, 那么只能不完整恢复)
- All unarchived redo log files and a datafile are lost.
- User error
- An important table was dropped.
- Invalid data was committed in a table.
Missing archive: A complete recovery operation fails because of a bad or missing archived log. Recovery can only be completed to a time in the past, prior to applying the archived log.
Loss of control files : You did not mirror your control file and you do not know the structure of your database, but you have a backup of an old binary copy.
Loss of redo logs: Redo logs were not mirrored and you lost a redo log before it was archived, along with a datafile. Recovery cannot continue past the lost redo log.
User error: A user drops the wrong table, commits data updated with an incorrect WHERE clause, and so forth.
3 种类型的 不完整恢复
- Time-based recovery : 故名思议, 恢复到之前的一个时间点.
- Cancel-based recovery : 跟 redo log sequence 有关. 下边有例子, 参考蓝色例子
- Change-based recovery : 恢复到之前一个 SCN.
另外, 如果你需要使用旧的 control file 来进行不完全恢复, 那么要使用 recovery using a backup control file. ( 这种情况一般用于 all control files are lost, 只剩下之前备份的control file了.
执行不完整恢复的需要注意的内容 :
1. 在进行不完整恢复之前, 先保存所有的数据库文件到其他目录, 包括 redo log 和 archive log. (防止你在操作的时候对数据库造成不可逆转的伤害, 如果实在不能全部备份, 最起码也要备份 control file 和 archive log file)
2. 在没有确认所有的恢复成功之前, 不要让用户可以访问数据库.
3. Back up (and later remove) archived logs from the system to prevent mixing archives from different database incarnations.
例如:
- A database at log seq 144 has archived logs from arch_120.rdo to arch_143.rdo.
- After performing incomplete recovery, a new database incarnation is created, setting the database log seq to 0.
- Archived log arch_120.rdo to arch_143.rdo are now part of the old database incarnation.
- After 120 log switches, the archived log arch_120.rdo will be overwritten, and is backed up with all other archives(including the old archived logs arch_121.rdo to arch_143.rdo). 两个database 的 archivelog 混在一起了 mixing
- At a later stage, if recovery requires arch_124.rdo, you need to make sure that the archived log restored from the backup is for the correct database incarnation, otherwise an error will result.
4. 在备份和恢复之前, 要一直确认 Alert Log file, 因为所有的流程的信息都会被存储在 alert log file 里.
执行不完整恢复的步骤:
1. Shutdown and backup the database.
例如: shutdown immediate
2. Restore all datafiles. Do not restore the control file, redo logs, password file, or parameter file.
这一步的目的是, 将所有的 datafile 和 archivelog file 备份一下, 是将目前数据库目录中的数据文件和 archivelog文件copy 到别的地方.
3. Mount the database.
startup mount;
4. Recovery the datafiles to a point before the time of failure.
recover database until cancel
recover database until time ‘2014-03-14:14:22:22’
recover database until time ‘2014-03-14:14:22:22’ using backup controlfile -- 使用以前备份的控制文件
recover [automatic] database <option> , 其中:
automatic 表示: 自动应用 archived 和 redo log files.
option: until time ‘YYYY-MM-DD:HH:MI : SS’;
until cancel;
until scn <integer>;
using backup control file;
5. Open the database with RESETLOGS.
alter database open resetlogs;
archive log list; -- 可以看到目前的 log sequence 号码, 例如上边说明, 之前的 seq 号已经到了 144, 可能你恢复完以后就看到 seq 号为0, 那么表示恢复成功了.
6. Perform a closed database backup.
shutdown immediate;
copy 所有的文件, 备份起来(全备), 注意, 全备以后, archivelog 文件就没有用了, 前面也提到了, 如果继续使用, 会出现混合mixing, 所以全备以后, 删除所有的数据库指定目录的archivelog 文件, 至于你在恢复之前的 archivelog 文件, 是否删除自己考虑, 因为对目前数据库没有影响(存储在别的目录)
注意: 由于数据库恢复到了之前的一个时间点, 那么该时间点之后的正确事务要再进行一次.
例子:
cancel-based recovery 例子 (跟日志文件有关)
假设:
现在是12:00, EMPLOYEES table was dropped while someone was trying to fix bad blocks, log files 同时存放在这个磁盘上, 这个 table 是在上午 11:45 左右被删除的, 现在开会: 开会发现:
redo log 没有多路复用, 换句话丢失的 redo log 没有镜像. 1 个 redo log file missing. 并且丢失的这个 log file 也没有被归档. (log2a.rdo 丢失)
现在有的 redo log 包含了 11:34 的信息. 26 分钟的数据丢失了. 通过 v$logfile 可以看到这个时间.
这时候查询 v$log_history 可以看到 缺失的那个 log seq 号, 这里是 48.
恢复的步骤与前面基本相同, 只是恢复的命令是 recover database until cancel. 注意, 这样是恢复到了(recover the database until log seq 48) 前面seq 47 的内容全面恢复了, 恢复完以后, 可以查看该 EMPLOYEES, 看到该内容可以查找的到.
Using backup control file recovery :
假设:
现在是12:00, tablespace containing the EMPLOYEES table has been dropped. The error occurred around 11:45, Many employee records were updated this morning, but not since 11:00. 并且每天晚上都会做一次备份.
事件顺序:
1. someone, drop tablespace emp_ts including contents;
2. 立刻告诉所有用户退出登录, 你将数据库设置成 restircted, 限制用户登录, alter system enable restricted session;
3. 经过分析, 你找到了昨天晚上备份的 control file, 因为当前的 control file 将被覆盖, 所以你要先确认目前这个 control file 里的信息.
select * from v$log;
select tablespace_name, file_name from dba_data_files where tablespace_name = ‘EMP_TS’
通过以上确认, 可以发现
EMP_TS tablespace has one datafile.
The current log sequence number is 61.
You confirm that the tablespace was dropped at 11:44:54 ( 通过 alert_log file 中的时间戳, 可以确认这个操作的时间 )
datafile number 4 is offline.
4. shutdown the database, backup control files. 然后将之前备份的包含了该tablespace信息的 control file 和 datafile 移动到当前数据库文件的目录.
5. 要确认所有的 offline datafiles 都变成 online, because any offline files may be unrecoverable after recovery:
select * from v$recover_file; 看到有 offline的, 就 alter database datafile 4 online;
6. recover database until time ‘2001-03-09:11:44:00’ using backup controlfile;
7. alter database open resetlogs;
8. 确认 EMPLOYEES table 是否存在
9. 全备
10. 通知用户, 11:44 分之后的操作要重做.
Loss of Current Redo log files 丢失了当前正在使用的 redo log file
1. 当想要打开数据库时, 会得到错误, current log file 丢失.
2. 需要 recovery 了, 首先确认 log sequence number , select * from v$log; 假如 current log seq no. 是 61
3. 将原来备份的 datafile copy 到数据库指定的路径. 然后, recover until cancel, 这个操作会将数据库恢复到 log seq 到 60.
4. alter database open resetlogs
5. The database should now be operational, because any missing log files will be re-created.
Note: If log files need to be re-created on another disk due to media failure, use the ALTER DATABASE DROP LOG GROUP and ALTER DATABASE ADD LOG GROUP commands to create the log files manually.
6. 全备
Control file 专题