错误分类 |
恢复解决方案 |
介质失败 |
如果是少量的块损坏,使用块介质恢复;如果是大量的块、数据文件、表空间的损坏,可能需要对损坏的数据文件或者表空间执行完全恢复;如果是归档Redo日志文件或者联机Redo日志文件的丢失,那么只需要不完全恢复方式。 |
逻辑损坏 |
如果是程序员错误导致出现的问题,可通过补丁应用修复问题。对于无法修复的问题,也可采用介质恢复手段来恢复数据。 |
用户错误 |
根据不同用户错误,选择不同的Flashback技术恢复,使用Flashback技术恢复用户错误是首选方案。如果Flashback不能很好的恢复数据再考虑使用介质恢复或者表空间时间点恢复。 |
注意:恢复依赖于备份,当生产环境中部署完成就应该确保有一次数据库的全库备份,且确保归档Redo日志被打开。
二、SCN时间机制
SCN(System Change Number,系统改变号)是Oracle内容非常重要的时间机制,一致性、数据恢复都与SCN有着非常密切的关系。Oracle启动时,也是通过SCN的验证来确认数据库是否需要执行实例恢复的。虽然RAC有多个实例,但是只有一个数据库,SCN是对应数据库级别的改变号,所以在不同的实例产生的SCN都必须是唯一的、有序的,这是由SCN生成器完成的工作。系统时间和SCN之间可以非常容易的相互转换,下面是系统时间和SCN相互转换的例子:
SQL> select timestamp_to_scn(sysdate) from dual;
TIMESTAMP_TO_SCN(SYSDATE)
-------------------------
6980593
SQL> select scn_to_timestamp(6980593) from dual;
SCN_TO_ TIMESTAMP (6980593)
-------------------------
02-DES-13 11.12.21.000000000 PM
SQL>
以下为几种常见的SCN:
? 检查点SCN
查询当前最近的检查点SCN:
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
3.6555E+12
SQL>
每执行一次检查点就由CKPT进程来更新,这个SCN保存在控制文件中。检查点的执行能够确保检查点执行时刻数据的完整性和一致性。实例恢复也是从上一次检查点开始进行恢复,检查点执行的频率决定了Crash恢复或者实例恢复需要花费的时间。当发生日志切换或者请求的SGA空间不足等情况时就会触发检查点。发生检查点,DBWn进程会将所有的脏数据写回磁盘,从而能够确保已提交的一致性数据被写回磁盘。单个联机Redo日志文件越大,发生检查点的间隔时间可能越长,实例恢复的时间也相应地增长,日志文件的丢失也会导致更多的数据丢失。
? 最新SCN
执行以下SQL语句查看数据库最新的SCN:
SQL> select current_scn from v$database;
CURRENT_SCN
------------
3.6555E+12
SQL>
该SCN是最新生成的全局SCN,它在不断更新,并且只会增大不会减小。
? 数据文件SCN
执行以下SQL查看所有数据文件的SCN:
SQL> select checkpoint_change# from v$datafile;
CHECKPOINT_CHANGE#
------------------
3.6555E+12
3.6555E+12
3.6555E+12
3.6555E+12
3.6555E+12
3.6555E+12
6 rows selected.
SQL>
每个数据文件都有一个数据文件SCN,每执行一次检查点便由CKPT进程来更新一次,该SCN保存在控制文件中。
? 启动SCN
执行以下SQL语句查询所有数据文件的启动SCN:
SQL> select checkpoint_change# from v$datafile_header;
CHECKPOINT_CHANGE#
------------------
3.6555E+12
3.6555E+12
3.6555E+12
3.6555E+12
3.6555E+12
3.6555E+12
6 rows selected.
SQL>
每个数据文件都有一个启动SCN,没执行一次检查点都由CKPT进程来更新一次,该SCN存储在数据文件头中。
? 终止SCN
执行下面SQL语句查询所有数据文件的终止SCN:
SQL> select last_change# from v$datafile;
LAST_CHANGE#
------------
6 rows selected.
SQL>
每个数据文件都有一个终止SCN,没执行一次检查点都由CKPT进程更新一次。该SCN保存在控制文件中,当数据库打开时,由于没有终止SCN存在,所以看到的是空,表示无穷大。
数据库启动过程中,首先会检查控制文件和数据文件的检查点执行次数是否一致,如果不一致需要对数据文件进行介质恢复。如果一致,进一步检查数据文件的启动SCN和终止SCN是否相同。如果数据库是非正常关闭,那么终止SCN肯定是空,这个时候需要执行Crash恢复或实例恢复的过程。Crash恢复或实例恢复过程需要用到联机Redo日志和UNDO表空间执行前滚和回滚操作,如果联机Redo日志或者UNDO表空间被损坏,那么数据库可能无法正常打开。如果启动SCN和终止SCN相同,那么数据库就可以正常打开。
? 日志SCN
执行以下SQL语句查询与日志相关的SCN:
SQL> select status,first_time,first_change#,next_time,next_change# from v$log;
STATUS FIRST_TIME FIRST_CHANGE# NEXT_TIME NEXT_CHANGE#
-------------------- -------------- ------------- -------------- ------------
INACTIVE 02-12鏈13 3.6555E+12 02-12鏈13 3.6555E+12
CURRENT 02-12鏈13 3.6555E+12 2.8147E+14
CURRENT 02-12鏈13 3.6555E+12 2.8147E+14
INACTIVE 02-12鏈13 3.6555E+12 02-12鏈13 3.6555E+12
SQL>
在上面查询中,first_time表示该日志组开始的时间,first_change#表示该日志组开始的SCN。可以看到,状态为current的日志组的first_change#值与前面讨论到的检查点的SCN值相同,说明发生日志切换的时候会触发检查点生成一致的检查点SCN。Next_time表述结束日志组的时间,next_change#表示结束日志组的SCN,该SCN值等于下一个日志组的first_change#值。当前日志组的next_time为空,next_change#是一个很大的值。
三、日志线程与联机Redo日志
Redo日志记录了数据的所有操作,以及操作的顺序。Redo日志主要包括联机Redo日志、归档Redo日志和Standby Redo日志三种类型,这三种类型的日志在结构上是完全相同的,只有用途不同而已。
Redo数据只有在数据库恢复时才能体现出它的价值。在RAC环境中,每个实例的归档Redo日志可以存放在本地文件系统,但是恢复的时候需要将所有节点的归档Redo日志放在一起,确保恢复的实例能够访问到所有实例的归档Redo日志。
每个实例都对应一个维护日志的日志线程(Redo thread),单实例只有一个线程号为1的日志线程。对于RAC来说,日志线程与实例的关系可以通过以下SQL语句查询得到。
1) 查询来自控制文件的线程信息:
SQL> select thread#,checkpoint_change#,last_redo_change# from gv$thread;
THREAD# CHECKPOINT_CHANGE# LAST_REDO_CHANGE#
---------- ------------------ -----------------
1 3.6555E+12 3.6555E+12
2 3.6555E+12 3.6555E+12
1 3.6555E+12 3.6555E+12
2 3.6555E+12 3.6555E+12
SQL>
2) 查询线程与实例之间的关系:
SQL> select thread#,instance_name from gv$instance;
THREAD# INSTANCE_NAME
---------- ------------------------------------------------
1 PROD1
2 PROD2
SQL>
3) 查询线程与日志组之间的关系:
SQL> select group#,thread# from v$log;
GROUP# THREAD#
---------- ----------
1 1
2 1
3 2
4 2
SQL>
四、UNDO表空间
UNDO表空间存放的是数据块的前镜像,是块的多版本数据,用于数据库恢复、一致性读和事务回滚,对数据库并发下读一致性起着重要的作用。
在RAC环境中,与连接Redo日志一样,每个实例都有自己的UNDO表空间,UNDO表空间必须放在共享存储上,每个实例都能访问到所有实例的UNDO表空间,以便任一活动实例都能执行所有实例的恢复操作。每个实例都有自己独立的UNDO表空间还能减少实例间对UNDO表空间的争用。
实例对应的Redo日志组由Redo线程来指定,实例对应的UNDO表空间是直接通过初始化参数文件中的参数指定。下面是参数文件中指定UNDO表空间对应实例的参数:
Prod01.undo_tablespace = ‘UNDOTBS1’
Prod02.undo_tablespace = ‘UNDOTBS2’
1. UNDO参数
l UNDO_MANAGEMENT初始化参数
UNDO_MANAGEMENT指定系统使用的UNDO空间管理模式。设置为AUTO,实例打开自动化UNDO管理模式;设置为MANUAL表示使用回滚段的手动管理模式自动UNDO管理(AUM)是从Oracle9i开始引入,以代替回滚段,也可以称为系统管理UNDO(SMU)。自动UNDO管理自动分配和管理DML操作所需空间的UNDO表空间,代替分配很多不同大小的回滚段。
l UNDO_RETENTION初始化参数
UNDO_RETENTION指定的是事务提交之后UNDO数据保留的时间。事务提交之后,UNDO数据不再需要用于回滚或者事务恢复,但一致性读可能还需要用到这些UNDO数据。
l UNDO_TABLESPACE初始化参数
每个数据库可以有多个UNDO表空间,但是对于每个实例只有一个活动的UNDO表空间。在RAC环境中,每个实例都对应一个UNDO表空间,UNDO_TABLESPACE用于指定实例对应的UNDO表空间。UNDO表空间无法进行收缩,如果UNDO表空间过大,只有通过替换的方式缩小UNDO表空间的大小。
l GUARANTEED UNDO RETENTION特性
默认guaranteed undo retention特性是禁用的,如果启动这个特性意味着数据库不能覆盖已提交但保留时间为超过undo_retention指定时间的UNDO数据。启用这个特性需要更大的UNDO表空间来支撑,如果UNDO表空间没有足够的空间会导致DML操作分配UNDO段失败。启用这个特性能够缓解出现ORA-01555错误几率,确保在一定的时间内能够使用部分Flashback特性闪回数据。执行以下SQL语句启用UNDO表空间的RETENTION特性:
SQL> alter tablespace undotbs1 retention guarantee;
2. UNDO视图
l V$undostat视图
V$undostat是v$rollstat的代替和提升,包含很多对UNDO空间的监控和统计信息。这个视图对于了解实例对UNDO空间的使用情况非常有用,能够通过监控估算出当前负载需要的UNDO表空间大小,能够根据统计信息提供建议调整UNDO_RETENTION,还能够找出长时间运行的SQL语句。在系统中,数据也使用这个视图提供的信息调整UNDO表空间的使用。只有自动化UNDO管理模式才能使用该视图。
l dba_undo_extents视图
dba_undo_extents描述了在数据中所有undo表空间包含的区间。这个视图显示UNDO中每个区间大小。执行以下SQL语句显示UNDO表空间中不同区间状态的统计信息。
l v$transaction
l dba_rollabck_segs视图
Oracle实例恢复
实例恢复
Oracle实例在非正常关闭或执行SHUTDOWN ABORT强制关闭后,实例在下次打开数据库之前会执行实例恢复过程,这个过程是由Oracle自动完成的。执行实例恢复的目的是确保数据的一致性,只有当联机Redo日志文件和UNDO表空间的介质没有被破坏才能确保实例恢复能够成功。
1. RAC的实例恢复
当软件、硬件或者人为问题导致实例失败之后,Oracle数据库自动使用联机Redo日志和UNDO数据执行实例恢复操作。
Crash恢复与实例恢复的区别:
l 一个单实例数据库或者RAC数据库所有实例失败之后,第一个打开数据库的实例会自动执行实例恢复。这种形式的实例恢复称为Crash恢复。
l 一个RAC数据库的一部分但不是所有实例失败后,在RAC中幸存的实例自动执行失败实例的恢复称为实例恢复。
根据Crash恢复和实例恢复的不同,由幸存实例或者第一个重启的实例读取失败实例生成的联机Redo日志和UNDO表空间数据,使用这些信息确保只有已提交的事务被写到数据库中,回滚在失败时候活动的事务,并释放事务使用的资源。
2. 实例恢复的阶段
在实例发生异常终止的情况下,数据库处于以下的状态:
l 事务提交的数据块只写入联机Redo日志中,没有更新到数据文件(那么未写入数据文件的更新必须重新写入数据文件)。
l 由于DBWR进程是异步向磁盘写入数据的,数据文件中可能包含没有被提交但已经写入数据文件的改变,这些改变必须回滚到之前的状态,以确保数据的一致性。
实例恢复利用联机Redo日志文件解决第一个问题,利用UNDO数据同步数据文件解决第二个问题,从而确保数据库数据的一致性。
因此,实例恢复过程会经历两个阶段:
u 实例恢复的第一个阶段称为Cache恢复或者前滚,确保联机Redo日志中所有已提交的事务操作的数据写回到数据文件中。如果正在执行的检查点还未完全执行完毕时发生实例失败,前滚过程可能需要通过多个联机Redo日志文件才能使数据恢复到之前时间的状态。前滚之后,数据中就包含了连接Redo日志文件中所有已提交的数据。在失败之前,数据文件中可能也包含未提交的改变,或者是记录在联机Redo日志中但未提交的数据,在前滚的时候被写到硬盘中。
u 实例恢复的第二个阶段称为回滚或者事务恢复,Oracle数据库应用UNDO块回滚在数据块中未提交的改变,这些数据块是在失败之前或者Cache恢复期间被写入的。回滚完成之后,整个实例恢复才算完成,而Redo和UNDO的丢失或者损坏都可能导致实例恢复失败。Oracle数据库能同时回滚多个事务。所有在失败的时候是活动的事务都被打上了终止的标记,等待SMON进程回滚终止的事务。
数据库由SMON后台进程自动应用联机Redo日志文件中的条目和读取UNDO表空间中的数据完成实例恢复。
Oracle介质恢复
介质恢复是基于物理备份恢复数据,介质恢复技术是Oracle数据库出现介质故障时恢复的重要保障。
1. 介质恢复的过程
介质恢复包括块恢复、数据文件恢复、表空间恢复和整个数据库的恢复。介质恢复主要是针对错误类型中的介质失败,如果是少量的块失败,可以使用介质恢复中的块恢复来快速修复;但如果是其它情况的丢失,根据具体情况,可使用数据文件恢复、表空间恢复甚至全库恢复。
介质恢复过程包括还原(RESTORE)和恢复(RECOVER)两个步骤:
还原是将某个时间点数据文件的拷贝再拷贝回去,还原后的数据库处于不一致性的状态,或不是最新的状态,还需要执行恢复操作。恢复就是使用归档Redo日志文件和联机Redo日志文件将不一致的数据库应用到一致性状态。如果是完全恢复,数据库就是最新的一致性状态;如果是不完全恢复,数据库是非最新的一致性状态。
| 注意:还原只是建立在数据库备份的基础版本上,例如,如果数据库备份包括0级备份和很多1级备份,还原只是应用0级备份,恢复过程会根据情况自动应用1级备份或Redo日志将数据库恢复到一致性的状态。 |
数据库的恢复过程又分为完全恢复和不完全恢复:
u 完全恢复
完全恢复是一种没有数据库丢失的恢复方式,能够恢复到最新的联机Redo日志中已提交的数据。在传统恢复方式中,因介质失败破坏了数据文件之后,可以在数据库、表空间和数据文件上执行完全介质恢复。
u 不完全恢复
不完全恢复是一种与完全恢复相反的恢复方式,是一种丢失数据的恢复方式,也称为数据库时间点恢复。通常情况下,若Flashback Database没有启用或者变得无效,可以执行不完全恢复撤销一个用户错误,不完全恢复不一定在原有的数据库环境执行,可以在测试环境下执行不完全恢复,将找回的数据再重新导入生产库中。对于不完全恢复来说,只能执行整个数据库的恢复,不能执行某个数据文件或表空间的不完全恢复。
不完全恢复根据备份情况恢复到与指定时间、日志序列号和SCN具有一致性的数据,之后的数据都将丢失。执行不完全恢复一方面是因为归档Redo日志、联机Redo日志的丢失不得不执行不完全恢复,另一方面可能是因为在某个时刻错误地操作了数据,过了一段时间之后才发现问题,而其它的恢复手段都无法恢复数据,这时也不得不使用不完全恢复来找回数据。
执行不完全恢复必须从备份中还原所有的数据文件,备份文件必须是要恢复的时间点之前创建的。当恢复完成,使用RESTLOGS选项打开数据库,将重新初始化联机Redo日志,创建一个新的日志序列号流,日志序列号从1开始,RESETLOGS之后的SCN还是在递增。
2. 物理坏块和逻辑坏块
Oracle数据文件的坏块可以分为物理坏块和逻辑坏块。物理坏块指的是块格式本身已经损坏,块内的数据没有任何意义。而逻辑坏块,指的是块内的数据在逻辑上存在问题,比如说索引块的索引值没有按从小到大排列导致的逻辑坏块。物理坏块一般是由于内存问题、OS问题、I/O子系统问题或硬件引起的,逻辑坏块一般是有Oracle bug等原因引起的。
各种各样的块损坏通常是通过Oracle的ORA-1578错误报告出来的,详细的损坏描述会在告警日志中打印出来。
l 物理块损坏
块的物理损坏有很多种情况,例如块头(Cache Header)被一个不正确的值替换、块被破坏或变得不完整、块的头和尾不匹配、块的校验和(CHECKSUM)不正确、块错位、块被归零。
n 破裂块
一个破裂块的意思即块是不完整的,块头的信息不能匹配块尾的信息。在告警日志中可能出现如下的日志信息:
Corrupt block relative dba:0x0380e573(file 14,block 58739)
Fractured block found during buffer read
……
n 不正确的校验和
块的校验和也是数据块的一致性检查的依据。块的一致性检查由DB_BLOCK_CHECKSUM和DB_BLOCK_CHECKING两个初始化参数控制。DB_BLOCK_CHECKSUM是一种物理检查,DB_CHECK_CHECKING是一种逻辑检查。
参数1 DB_CHECK_CHECKSUM
DB_BLOCK_CHECKSUM只有在写入(DBWn常规写或用户进程直接路径写入)时,根据一个CHECKSUM算法计算数据块的校验和,然后写入数据块的一个特定位置(CACHE HEADER,具体是以0字节算起,块的第16~17字节),在读取块时再进行检验。主要是防止I/O硬件和I/O子系统的错误。
CHECKSUM的算法只是根据块的字节值计算一个校验和,算法比较简单。该参数默认在所有表空间上都起作用。
DB_BLOCK_CHECKSUM参数属性
属性 |
描述 |
语法 |
DB_BLOCK_CHECKSUM={OFF|FALSE|TYPICAL|TURE|FULL} |
默认值 |
TYPICAL |
修改范围 |
ALTER SESSION,ALTER SYSTEM |
只有当参数值是TYPICAL或者FULL,并且块的最后一次写是存储了一个校验和时,读取这个块,校验和才会被验证。在FULL模式,Oracle用update/delete语句改变数据之前会验证校验和,改变被应用之后还会重新计算校验和。
从Oracle Database 11g开始,大多数日志校验和都是通过前台进程产生的,同时LGWR执行其余的工作,这是为了更好地发挥CPU和缓存的效率。当这个参数设置为FULL,写日志块到磁盘之前,LGWR验证通过前台进程生成的每个日志块的校验和。在Oracle Database 11g之前的版本中,LGWR独自执行日志块校验和。数据文件块的校验和是由DBWR进程负责计算和管理的。
这个参数设置为OFF时,DBWn只为SYSTEM表空间计算校验和,不为用户表空间计算校验和。另外,此时数据库也不会执行日志的校验工作。
校验和可以使Oracle数据库察觉到磁盘、存储系统或者I/O系统引起的损坏。如果设置为FULL,DB_BLOCK_CHECKSUM也会捕捉在内存中的损坏,并停止它们对磁盘的操作。设置这个参数为TYPICAL值只会引起系统额外的1%~2%的负载,设置为FULL会引起4%~5%的负载。Oracle推荐设置DB_BLOCK_CHECKSUM为TYPICAL。为了保持向后兼容性,TRUE和FALSE值被保留,TRUE等同于TYPICAL,FALSE等同于OFF。
如果DB_BLOCK_CHECKSUM不等于FALSE值,每次读取块,Oracle计算校验和,都与存储在块头中的校验和进行对比。如下例子:
Corrupt block relative dba: 0x0380a58f (file 14,block 42383)
Bad check value found during buffer read
……
参数2 DB_BLOCK_CHECKING
DB_BLOCK_CHECKING参数主要是用于数据块的逻辑一致检查,但只是在块内,不包括块间的逻辑检查。主要用于防止在内存中损坏或数据损坏。
无论该参数如何设置,对SYSTEM表空间来说,逻辑一致检查始终处于“打开”状态,在其他表空间该参数默认是关闭的。
DB_BLOCK_CHECKING参数的属性
参数值 |
含义 |
OFF或者FALSE |
对于用户表空间没有任何逻辑一致性检查工作 |
LOW |
块的内容在内存中改变之后,执行基本的块头检查,如UPDATE语句、INSERT语句、磁盘读或者在RAC中内部实例之间的块传递之后发生检查工作 |
MEDIUM |
除了索引以外的所有对象执行LOW检查和完全语义检查,由于索引能在遭遇损坏的情况下的重建,所以可以不考虑对它检查 |
FULL或者TRUE |
所有对象执行MEDIUM检查和完全语义检查 |
Oracle通过遍历在块中的数据来检查一个块,确保它在逻辑上手尾一致。根据系统负载和参数值,块检查通常一起1%~10%的负载。打开块检查,大量的UPDATE或者INSERT将造成更大负载,对于一个繁忙的系统,特别有大量插入或者更新操作的系统来说,性能影响是比较明显的。如果性能负载可以被接受,应该考虑设置DB_BLOCK_CHECKING为FULL。为了保持向后的兼容性,TURE和FALSE参数值同样可以使用,FALSE等同于OFF,TRUE等同于FULL。
如果启用DB_BLOCK_CHECKING参数,在磁盘的块发生逻辑损坏,下一次块更新将作为软损坏标记这个块,之后读取这个块产生ORA-1578的错误。
n 块错位
当Oracle察觉读取块的内容属于不同块但是校验和又是正确的时,会产生错误。
l 逻辑块损坏
若块包含一个正确的校验和,块头以下的结构是损坏的(块内容损坏),这可能引起不同的ORA-600错误。逻辑块损坏的详细损坏描述通常不会打印到告警日志。DBV将报告块具体的逻辑错误。
3. 坏块的检测工具
以下为损坏块的检测工具和使用方法:
l DBVERIRY坏块验证工具
DBVERIRY不能验证联机Redo日志、归档Redo日志、控制文件和RMAN备份集,只能用于数据文件的块验证。
n DBV验证传统数据文件
下面是使用DBV工具验证数据文件块的例子:
$ dbv file=/testdb/test01.dbf blocksize=8192
注意:DBV工具除了用于检测数据文件是否有坏块外,也用于获得坏块的详细信息。
n DBV验证裸设备数据文件
DBV要求file后面跟的必须是一个包含扩展名的文件,所以如果数据库使用裸设备作为存储方式,就必须使用ln命令连接裸设备一个带扩展名的文件,然后使用DBV工具通过对链接文件的验证实现对裸设备数据文件的验证。
n DBV验证ASM存储的数据文件
如果是验证存储在ASM中的数据文件则需要指定用户名和密码,如果不指定用户名和密码,将收到DBV-00008:USERID must bu specified for OSM files的报错。下面是使用DBV工具验证存储在ASM中的数据文件的块的例子:
$ dbv file=+DATAFILE/testdb/datafile/test.234.648839 userid=sys/oracle
l ANALYZE命令
Analyze命令的主要目的是通过分析数据库对象,为优化器收集数据库对象的统计量信息,以便优化器生成准确的执行计划。同时,它也能检查某个表或索引是否存在损坏的情况。Analyze执行坏块检查,但是不会标记坏块为corrupt,检测结果保存在USER_DUMP_DEST目录下的用户trace文件中。Analyze语法:
Analyze table/index / validate structure ;
Analyze命令会验证每个数据块、每条记录和索引的完整性。CASCADE关键字表示验证表及其相关的所有索引。与DBVERIFY不同的是,analyze只验证高水位线以下的数据块,analyze不会对未使用的空间进行验证。
SQL> analyze table fengpin.test validate structure;
l RMAN工具
RMAN是一块备份工具,就像一个过滤器,RMAN需要通过缓存过滤每一个块,其中一个特点就是检查块是否被损坏。如果备份的数据库中包含有坏块,将会收到错误
l EXP工具
对于包含坏块的表执行导出操作,会收到相关的错误信息。对于这种情况,在非归档模式无法通过块恢复修复块的情况下,有如下两种处理方法:
方法1:启用10231事件
通过设置10231诊断事件可以在导出的时候让Oracle忽略表损坏的块,10231是Oracle的内部诊断事件,设置在全表扫描时跳过坏块的数据块,只导出包含正确块的数据,之后把表删除,再把导出的表数据导入新表,从而修复该表。
1) 启用10231诊断事件
SQL> alter system set events=’10231 trace name context forever,level 10’;
2) 禁用10231诊断事件:
SQL> alter system set events=’10231 trace name context forever,level 0’;
方法2:使用DBMS_REPAIR包标记损坏的块。
可以使用DBMS_REPAIR包标记损坏的数据库对象,这样在对损坏的对象执行全表扫描的时候会跳过损坏的块。语法如下:
SQL> exec dbms_repair.skip_corrupt_blocks(‘’,’tablename’);
EXP坏块检查有一定的局限性,不会发现如下类型的坏块:
ü HWM(高水位线)以上的坏块
ü 索引中存在的坏块
ü 数据字典中存在的坏块
l Expdp工具
使用expdp工具不会给出坏块的提示,只会将对象正确的数据导出。
4. 块的损坏与恢复
块已经不是Oracle的格式,或者其内部是不一致的,那么这个块就被认为已损坏。块介质恢复是当数据文件是联机时,还原和恢复数据块的技术。如果只有一些块被破坏,那么块介质恢复是较好的恢复选择。
BBED(Block Brower and EDitor)是Oracle的一款内部工具,可以用来直接查看和修改Oracle数据文件块的内容。BBED是一个针对Oracle的二进制编译工具。该工具不受Oracle支持,默认是不生成可执行文件的,在使用钱需要重新编译。
1) 编译BBED
直接在Oracle 11gR2 的环境中编译BBED,将收到以下错误信息:
$ cd $ORACLE_HOME/rdbms/lib
$ make –f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
……
gcc: /u01/app/oracle/11.2.0/db_1/rdbms/lib/ssbbded.o: No such file or directory
gcc: /u01/app/oracle/11.2.0/db_1/rdbms/lib/sbbdpt.o: No such file or directory
Oracle 11gR2 环境中编译BBED可执行文件所需要的ssbbded.o和sbbdpt.o对象文件被移除,不过可以从Oracle 10g环境中将这两个文件拷贝到Oracle 11g环境中进行编译。
除了将上面的ssbbded.o和sbbdpt.o文件拷贝到Oracle 11g环境外,BBED还需要用到$ORACLE_HOME/rdbms/mesg目录下的bbedus.msg和bbedus.msb两个信息文件,这几个文件都需要从Oracle 10g中拷贝到Oracle 11g中对应的目录中。下面是将以上4个文件从Oracle 10g中拷贝到Oracle 11g对应目录之后的编译过程:
$ cd $ORACLE_HOME/rdbms/lib
$ make –f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
$ file bbed
$ size bbed
$ ldd bbed
$ cp bbed $ORACLE_HOME/bin/
$ cd /
$ which bbed
/u01/app/oracle/product/11.2.0/db_1/bin/bbed
编译成功后登录BBED,登录时需要密码(默认密码是:blockedit)
$ bbed
2) BBED模拟表数据块的损坏
a. 创建测试表
SQL> create table test.testbbed as select * from dba_tables;
b. 创建BBED参数文件
由于BBED无法对ASM进行操作,所以这里将表创建到ACFS文件系统的存储设备上。这里创建两个BBED参数文件,filelist.txt保存要操作的数据文件的ID和路径,bbed.par保存数据文件的块大小、filelist.txt的位置和操作模式:
$ more filelist.txt
6 /testbbed/tbtbs01.dbf
$ more bbed.par
blocksize=8192
listfile=filelist.txt
mode=edit
filelist.txt的内容可通过select file_id,file_name from dba_data_filesSQL查询得到。
c. BBED基本操作
ü 使用指定的参数文件登录BBED:
$ bbed parfile=bbed.par
ü 显示BBED配置文件中指定的数据文件信息:
BBED> info
ü 设置要操作的数据文件:
BBED> set file 6
ü 显示要操作的数据文件的详细信息:
BBED> show
d. 模拟坏块
修改文件号为6的第136号块:
BBED> modify 1000 file 6 block 136
如果修改错误,可以执行revert命令回滚。
e. 验证坏块
在BBED执行以下命令验证数据块,发现block 136已经损坏
BBED> verify
f. 使用DBV工具验证
使用DBV工具验证发现file 6 block 136已经损坏
$ dbv file=/testbbed/tbtbs01.dbf blocksize=8192
g. 执行块读取操作
执行一个test.testbbed的全表扫描,收到ORA-01578错误
SQL> alter system flush buffer_cache;
SQL> select /*+FULL(T)*/ COUNT(1) FROM TEST.TESTBBED T;
3) RMAN的块恢复
块介质恢复用来恢复一个单独的块或者数据文件中数据块的集合,如果是小数据量的数据丢失或损坏,而不是整个数据文件,这种类型的恢复是很有用的。通常,块损坏会在跟踪文件中报告错误信息。
块级别的数据丢失通常是由以下两个原因造成的:
n I/O错误引起的镜像数据丢失。
n 内存损坏,刷新到磁盘。
a. 使用RMAN BLOCKRECOVER命令的注意事项
n 目标数据库必须在MOUNT或者OPEN状态,如果执行某个数据文件的块介质恢复,那么该数据文件不能是脱机状态。
n 块介质恢复不支持基于时间点的块恢复。
n 只能在损坏的块上执行块介质恢复。
n 块被标记为介质损坏之后是不能访问的,直达恢复完成。
n 当使用备份的控制文件加载数据库时,不能执行块的介质恢复。
n 必须有一个包含损坏块文件的全备份,块介质恢复不能使用增量备份。
n 如果RMAN访问块介质恢复需要特定归档Redo日志文件失败,那么将执行还原FAILOVER,尝试使用RMAN资料库中列出的适合这个操作的所有其它备份,如果没有合适的备份存在执行才会失败。
n 数据文件头不能被恢复
n 不能在非归档模式下执行块介质恢复。
b. RMAN BLOCKRECOVER命令的使用方式
RMAN BLOCKRECOVER命令有以下三种使用方式:
方式1 使用BLOCKRECOVER CORRUPTION LIST命令恢复在V$DATABASE_BLOCK_CORRUPTION视图中报告的所有块:
RMAN> blockrecover corruption list;
方式2 使用BLOCKRECOVER 命令的时候指定文件号和块号:
RMAN> blockrecover datafile block ;
方式3 执行blockrecover命令的时候指定表空间和数据块地址(DBA):
RMAN> blockrecover tablespace DBA ;
c. RMAN BLOCKRECOVER使用的例子
例子1 恢复3个数据文件的损坏块:
RMAN> BLOCKRECOVER DATAFILE 2 BLOCK 12,13 DATAFILE 3 BLOCK 5,98,99 DATAFILE 4 BLOCK 19;
例子2:从数据文件拷贝中还原、恢复一系列块:
RMAN> RUN
{
BLOCKRECOVER DATAFILE 3 BLOCK 2,3,4,5 TABLESPACE sales DBA 4194405,4194409,4194412 from DATAFILECOPY;
}
例子3:从指定的tag备份总还原、恢复块
RMAN> BLOCKRECOVER TABLESPACE SYSTEM DBA 4194404,4194405 FROM TAG “weekly_backup”;
例子4:从用于恢复数据到两天以前的备份中还原、恢复SYSTEM表空间中的两个块:
RMAN> BLOCKRECOVER TALBESPACE SYSTEM DBA 4194404,4194405 RESOTRE UNTILL TIME ‘sysdate-2’;
例子5:运行备份验证数据库,修复在V$DATABASE_BLOCK_CORRUPTION中记录的所有损坏块:
RMAN> BACKUP VALIDATE DATABASE;
RMAN> BLOCKRECOVER CORRUPTION LIST;
4) 确定损坏块对应的对象
要确定一个损坏的对象需要知道AFN(Absolute File Numbe,绝对文件号)和BL(Block Number,块号)。AFN和RFN(Relative File Number,相对文件号)通常是相同的,但是也可能不同(特别是如果数据库从Oracle7迁移或者如果使用的是可传输、可插拔的表空间),获得正确的AFN和RFN就显得非常重要,如果指定了错误的AFN将导致找不到对象或错误识别对象。
a. 确定AFN和BL
方法1:从ORA-1578得到AFN
ORA-1578之后产生的ORA-1110错误提供AFN号码。
方法2:从DBVERIFY输出获得AFN。
通过使用DBV工具会报告损坏的块,DBV工具通过提供与相关的RDBA、RFN和BL信息。
方法3:从RMAN获得AFN
RMAN在V$DATABASE_BLOCK_CORRUPTION视图报告损坏的块。该视图的字段FILE#表示AFN,字段BLOCK#表示BL。
b. 定位损坏的对象
一旦AFN被识别,执行以下SQL语句定位损坏的对象:
SQL> select *
From DBA_EXTENTS
Where file_id=&AFN
And &BL BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS-1;
如果损坏的块是数据文件开头,这将导致数据库无法正常启动和关闭,并且使用RMAN BLOCKRECOVER也不能恢复。因此此时就要进行完全恢复或者尝试使用BBED修改块头。
1) 模拟损坏数据文件头的块
使用BBED方法将数据文件6的第1个块损坏,DBV的检查结果如下:
$ dbv file=/test/test01.dbf
2) 尝试使用RMAN BLOCKRECOVER进行恢复
执行以下命令使用RMAN的BLOCKRECOVER对数据文件6的第1个块进行恢复:
RMAN> blockrecover datafile 6 block 1;
Starting recover as 2013-12-07 16:24
Using channel ORA_DISK_1
Starting media recovery
Media recovery complete,elapsed time: 00:00:00
Finished recover at 2013-12-07 16:24
恢复显示是完成的,也没有报错。但是执行DBV验证命令发现标记的坏块还是两个,及没有真正修复。说明使用RMAN BLOCKRECOVER对数据文件头的修复是没有作用的。
尝试正常关闭数据库,由于数据库无法完成检查点工作,所以正常关闭操作失败:
SQL> shutdown immediate
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: ‘/test/test01.dbf’
ORA-01210: data file header is media corrupt
强制关闭数据库:
SQL> shutdown abort
重启数据库,发现数据库无法打开数据文件:
SQL> startup
……
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: ‘/test/test01.dbf’
ORA-01210: data file header is media corrupt
3) 执行数据文件的完全恢复
执行以下命令还原、恢复6号数据文件:
RMAN> restore datafile 6;
RMAN> recover datafile 6;
尝试打开数据库:
SQL> alter database open;
Database altered.
Oracle数据库中有各种各样的块,如空块、表头块、数据块、索引块、数据文件头块、UNDO段块等。如果损坏的是普通表的数据块,那即不会影响启动数据库,也不会影响其他表的正常访问,只是在访问该表的时候会出现问题。如果损坏的是数据文件的块头,那么将导致数据库无法正常启动和停止,执行块恢复不能修复这个问题,执行数据文件的完全恢复才能恢复数据文件块头的损坏或尝试使用BBED修改数据文件块头。
不完全恢复又称为数据库基于时间点恢复,是将整个数据库恢复到之前的某个时间点、日志序列号或者SCN号。如下不完全恢复的选项:
不完全恢复的选项
不完全恢复方式 |
RMAN选项 |
用户管理备份选项 |
恢复到某个时间点 |
until time |
until time |
恢复到某个日志序列号 |
until suquence |
until cancel |
恢复到某个SCN号 |
until SCN |
until change |
不完全恢复只能针对整个数据库而言,并不能执行数据文件和表空间的不完全恢复;另外,对于非归档模式的恢复来说,也不能执行不完全恢复。
1) 基于时间点的不完全恢复
RMAN> run {
shutdown immediate;
startup mount;
SQL “alter session set nls_date_format=’’YYYY-MM-DD HH24:MI:SS’’”;(两个单引号之间没有空格)
set until time ‘2013-12-07 17:24:00’;
restore database;
recover database;
alter database open resetlogs;}
SET UNTIL TIME时间可以使用多种表示方式,可以使用TO_DATE函数来表示时间,还可以使用SYSDATE-1方式来表示时间。
注意:不完全恢复是针对整个数据而言,如果在上面的脚本中,还原和恢复的是某个数据文件或表空间,那么脚本将忽略set until time设置,对数据文件或表空间进行完全恢复。对RESTORE命令指定until time或者until scn的意义在于这样可以自动选择最近的RMAN备份来恢复数据,以上的批量命令相当于为RESTORE和RECOVER都指定了until time子句,这样比单命令模式更加简单和合理。基于时间点的恢复不能恢复到最终备份完成时间点以前的时段。
2) 基于序列号的不完全恢复
基于序列号的不完全恢复须指定某个Redo线程的序列号,那么在这个序列号切换时间点之前的所有实例的归档日志都需要的,每个节点的负载不同,其他实例的序列号可能比指定的Redo线程序列号要大。
以下是在RMAN中基于日志序列号的不完全恢复的例子:
RMAN> run {
Shutdown immediate;
Startup mount;
Set until sequence 10350 thread 1;
Restore database;
Recover database;
Alter database open resetlogs;}
注意:指定线程序列号为10350,但是恢复是不包含该序列号的日志的,也就是说恢复只会恢复到thread 1 sequence 10304的日志,时间点和scn恢复同样如此。
3) 基于SCN的不完全恢复
下面是在RMAN中基于SCN的不完全恢复的例子:
RMAN> run {
shutdown immediate;
startup mount;
set until scn 324394;
restore database;
recover database;
alter database open resetlogs;}
注意:对打开的数据库执行的全库备份或者0级备份,即使不完全恢复到执行全库备份或者0级备份的备份时间点也可能需要部分Redo日志,原因在于对打开的数据库执行RMAN备份是一个不一致的备份。
表空间时间点恢复(Tablespace Point-in-time Recovery,TSPITR)特性可以恢复一个或更多的表空间早于数据库其他部分的某个时间点。表空间时间点恢复是表空间的不完全恢复,操作起来比较复杂。
表空间时间点恢复能在不影响数据库其它表空间和对象的情况下,恢复一个或更多的用户表空间到之前的某个时间点。表空间时间点恢复是对某个表空间执行基于某个时间点的恢复,是特殊的不完全恢复。RMAN TSPITR可以用于以下场景:
n 一个不正确的job或者DML语句破坏了数据库其中一个表空间的数据,RMAN TSPITR可用于被破坏表空间的恢复。
n DDL操作改变了表的结构之后,RMAN TSPITR可用于丢失数据的恢复。这种情况不能使用Flashback Table找回表之前的结构的数据,如表结构变化后的一个TRUNCATE表操作。
n 一个表被一个drop语句加了purge选项彻底drop。RMAN TSPITR可用于这种情况的恢复。
n 恢复drop的表空间,当没有使用恢复目录,RMAN能对被drop的表空间执行TSPITR。
n 从一个表的逻辑损坏中恢复。
表空间时间点恢复和Flashback有点类似,在没有介质失败的情况下,数据也可以使用Flashback Database找回,但是Flashback Database会导致整个数据库被闪回到之前的某个时间点。与TSPITR不同的是,Flashback Database特性必须产生Flashback日志,使用Flashback Database闪回数据库比使用TSPITR有更多的限制,TSPITR可以扩展到能找回可用于恢复的更早备份数据。
1) TSPITR的工作原理
TSPITR工作原理的5个步骤:
步骤1 在辅助实例上用目标数据库的备份集还原数据文件。
步骤2 在辅助实例上用目标数据库的归档文件恢复数据文件。
步骤3 在辅助数据库上导出相关数据。
步骤4 修改主库的控制文件。
步骤5 将辅助数据上导出的文件导入目标数据库。
2) RMAN TSPITR模式
表空间时间点恢复使用的是RMAN的RECOVER tablespace命令,执行RMAN TSPITR有几个选项,不同的选项协调各种不同的操作模式之间对特定环境的自动化操作。
a. 全自动化(默认方式)
在这种模式下,RMAN管理整个TSPITR过程。制定表空间的恢复集、辅助目的地、目标时间和允许RMAN管理所有TSPITR的其它方面。
b. 自动化
可以覆盖一些默认RMAN TSPITR设置,但仍然使用RMAN管理辅助实例和辅助目的地。这是默认方式的变种,RMAN TSPITR提供一些固定管理的同事允许手动指定一些参数,主要包含以下两个参数:
n 辅助集或恢复集文件的位置
n 初始化参数文件
除了在TSPITR之后的恢复集文件位置,在TSPITR期间的辅助集文件、通道设置和参数或辅助实例的其它方面等更多控制都推荐使用默认方式。全自动和自动化都是使用RMAN自动管理辅助实例。
c. 非自动化
使用这种模式是手动创建和管理辅助实例的所有方面和一部分TSPITR过程。当必须分配不同的通道或者使用用户管理辅助实例改变参数时,使用这种模式是合适的。
3) 执行全自动化的TSPITR
下面以默认的全自动化模式在目标数据库服务器创建辅助数据库构建TSPITR,恢复在目标数据库对表的一个误操作。目标数据库与辅助数据库都在一台服务器上,下表是两个数据库的实例名和数据库名称对照表:
数据库类型 |
实例名称 |
数据库名称 |
目标数据库 |
test |
test |
辅助数据库 |
test2 |
test |
a. 创建模拟环境
步骤1 在目标数据创建测试表空间xy_tbs:
SQL> create tablespace xy_tbs datafile ‘/u01/app/oracle/test/xy_tbs01.dbf’ size 5M;
步骤2 确保目标数据库处在归档模式,使用RMAN查找出xy_tbs表空间的file_id,对它进行备份:
RMAN> report schema;
……
RMAN> backup datafile 5;
步骤3 创建测试用户xiaoyang:
SQL> create user xiaoyang identified by xiaoyang default tablespace xy_tbs tempory tablespace temp;
SQL> grant create session,create table,unlimited tablespace to xiaoyang;
SQL> connect xiaoyang/xiaoyang;
步骤4 创建两个测试表:x1和x2,每个表插入一条测试数据:
SQL> create table x1(D date);
SQL> create table x2(D2 date);
SQL> insert into x1 values(sysdate);
SQL> insert into x2 values(sysdate);
SQL> commit;
步骤5 查看当前时间作为表空间的恢复时间点:
SQL> alter session set nls_date_format=’YYYY-MM-DD HH24:MI:SS’;
SQL> select sysdate from dual;
步骤6 在恢复时间点之后向x2表中插入一条数据和创建一个新表x3,向x3插入一条测试数据:
SQL> insert into x2 values(sysdate);
SQL> create table x3(D3 date);
SQL> insert into x3 values(sysdate);
SQL> commit;
步骤7 手动drop掉表x1:
SQL> drop table x1 purge;
假设drop x1表是一个误操作,现在要通过TSPITR恢复技术恢复该表。
b. 检查表空间是否自关联
执行以下SQL语句检查表空间自关联情况:
SQL> execute dbms_tts.transport_set_check(‘xy_tbs’,true,true);
SQL> select * from transport_set_violations;
如果查询transport_set_violations视图有值返回,说明表空间有自关联,需要手动处理提示的问题。
c. 标识TSPITR之后将会丢失的对象
步骤1 通过时间标识TSPITR之后将会丢失的对象:
SQL> select owner,name,tablespace_name,to_char(creation_time,’YYYY-MM-DD HH24:MI:SS’) from ts_pitr_objects_to_be_dropped where tablespace_name in(‘xy_tbs’) and creation_time > to_date(‘2013-12-08 09:43:00’,’YYYY-MM-DD HH24:MI:SS’) order by tablespace_name,creation_time;
步骤2 通过SCN标识TSPITR之后将会丢失的对象:
SQL> select owner,names,tablespace_name,to_char(creation_time,’YYYY-MM-DD HH24:MI:SS’) from ts_pitr_objects_to_be_dropped where tablespace_name in(‘xy_tbs’) and creation_time > to_date(to_char(scn_to_timestamp(1638492),’YYYY-MM-DD HH24:MI:SS’),’YYYY-MM-DD HH24:MI:SS’) order by tablespace_name,creation_time;
如果以上两个查询有结果返回,那么在执行TSPITR之前应该先将这些对象进行逻辑备份,TSPITR完成之后,再将这些对象以替换的方式导入,以恢复产生数据丢失的对象。
d. 创建辅助数据库参数文件
转储目标数据库参数文件,将该参数文件拷贝到$ORACLE_HOME目录,重命名为inittest2.ora,参考如下参数文件内容调整inittest2.ora实例的初始化参数文件:
*.audit_file_dest=’/u01/app/oracle/admin/test2/adump’
*.control_files=’/u01/app/oracle/oradata/test2/control01.ctl’
……
db_file_name_convert=(“/u01/app/oracle/oradata/test”,”/u01/app/oracle/oradata/test2”)
log_file_name_convert=(“/u01/app/oracle/oradata/test”,”/u01/app/oracle/oradata/test2”)
log_archive_start=false
lock_name_space=test2
修改test2实例初始化参数文件中的audit_file_dest、control_file参数,确保与原有数据库的存储位置不同。添加db_file_name_convert、log_file_name_convert、log_archive_start和lock_name_space参数设置。
e. 创建目录结构
根据实例test2参数的设置创建相应的目录结构:
$ mkdir –p /u01/app/oracle/admin/test2/adump
$ mkdir –p /u01/app/oracle/oradata/test2
f. 创建test2实例密码文件
$ cd $ORACLE_HOME/dbs/
$ orapwd file=orapwtest2 password=oracle entries=5
g. 创建辅助数据库实例的静态注册
在grid用户下的$GRID_HOME/network/admin/listener.ora文件中修改如下配置:
$ cat listener.ora
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = test2)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1)
(SID_NAME = test2)
)
)
h. 添加Oracle Net本地服务名
在Oracle用户下的$ORACLE_HOME/network/admin/tnsnames.ora文件中添加如下配置:
TEST2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rhel2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test2)
)
)
i. 启动辅助数据库到NOMOUNT状态
$ export ORACLE_SID=test2
$ sqlplus / as sysdba
SQL> create spfile from pfile;
SQL> startup nomount
j. 执行TSPITR恢复
使用RMAN同时连接到目标数据库和辅助数据库,使用RECOVER TABLESPACE命令执行TSPITR操作:
$ rman target /
RMAN> connect auxiliary sys/oracle@test2
RMAN> run {
allocate auxiliary channel a1 type disk;
allocate channel c1 type disk;
recover tablespace xy_tbs until time “to_date(‘2013-12-08 09:30:00’,’YYYY-MM-DD HH24:MI:SS’)”;
release channel c1;
}
执行TSPITR需要手动分配auxiliary通道
使目标数据中xy_tbs表空间ONLINE:
SQL> alter tablespace xy_tbs online;
k. 验证恢复结果
SQL> select * from xiaoyang.x1;
SQL> select * from xiaoyang.x2;
SQL> select * from xiaoyang.x3;
对于正常关闭的数据库来说,关闭前会执行一个检查点以保证数据库的一致性,重启之后,联机日志是是否存在都不会导致数据的丢失。然而,如果是非正常关闭的数据库,重启之后会执行实例恢复的过程,如果实例恢复过程需要的UNDO活Redo日志丢失,那么就可能造成数据的不一致和数据的丢失。
a. 连接Redo日志损坏的4种情况
联机Redo日志文件的损坏有以下4中情况:
情况1 非当前日志损坏,正常关闭数据库。
情况2 非当前日志损坏,非正常关闭数据库。
情况3 当前日志损坏,正常关闭数据库。
情况4 当前日志损坏,非正常关闭数据库。
b. 处理方法
1) 情况1和情况2的处理方法
情况1和情况2的处理方法一样,直接把日志文件清除即可:
SQL> alter database clear logfile group 3;
2) 情况3的处理方法
在SQLPLUS中执行以下的SQL语句以RESETLOGS模式重新打开数据库:
SQL> startup mount;
SQL> recover database until cancel;
SQL> alter database open resetlogs;
3) 情况4的处理方法
这种情况会导致联机Redo日志中的一部分已提交的数据丢失,实例恢复中的前滚操作不能成功执行,回滚操作也无法执行,这也会导致部分数据的丢失。处理方法是强制打开数据库或通过备份执行介质不完全恢复。
数据库的脱机包括数据文件的脱机和表空间的脱机,数据文件的脱机和表空间非正常脱机在下一次执行联机命令之前都无需先执行介质恢复操作,介质恢复成功才能联机成功。
数据文件添加到表空间之后不能再被删除,也没有语法支持这么做,如果不想使用该数据文件,唯一的方法是将数据文件设置为OFFLINE状态。执行以下步骤将数据文件设置为OFFLINE状态:
1) 如果是归档模式可以执行如下SQL语句设置数据文件的状态为OFFLINE:
SQL> alter database datafile ‘xxx.dbf’ offline;
2) 如果是非归档模式执行以下SQL语句将数据文件状态设置为OFFLINE:
SQL> alter database datafile ‘xxx.dbf’ offile drop;
即使数据文件脱机,数据文件相关的数据字典信息、元数据信息依然存在,当表空间被删除后,相关数据文件的信息才会被清除。Drop tablespace只是清空Oracle数据字典信息,即使数据文件不存在也可以正常的drop表空间。对于数据文件的脱机,在设置该数据文件OFFLINE的时候都需要对该数据文件执行介质恢复。
如果在非归档模式下使用OFFLINE drop使数据文件脱机,这就意味着该数据文件可能无法再恢复到online状态,原因在于非归档模式下可能没有足够的日志文件在执行online的时候完成介质恢复。如果数据文件脱机之后日志没有发生切换,所有需要的日志还依然存在的话,那么非归档模式下数据文件的脱机也可以再次变成online状态。
表空间脱机实际就是表空间对应的所有数据文件脱机。
表空间脱机分为正常脱机、临时脱机和立即脱机,如下:
1) 正常脱机
这是默认的选项,如果表空间正常脱机,当重新执行online的时候,Oracle会用相应的SCN来更新表空间数据文件头SCN即可正常地online表空间,而不需要执行介质恢复。执行以下SQL语句是表空间正常脱机:
SQL> alter tablespace xxx offline;
2) 临时脱机
当执行临时脱机(OFFLINE temporary)语句之前已经有表空间对应的数据文件脱机,那么在是表空间重新online之前需要执行特定数据文件的介质恢复。执行以下的SQL语句是表空间临时脱机:
SQL> alter tablespace xxx offline temporary;
3) 立即脱机
执行这个操作(OFFLINE immediate)表示立即使表空间脱机,在下次使表空间online的时候必须执行介质恢复,介质恢复成功之后表空间才能变成online状态。执行以下的SQL语句是表空间立即脱机:
SQL> alter tablespace xxx offline immediate;
...............................................................................................................................
● 本文来自于itpub转载文章,若有侵权,请联系小麦苗及时删除,非常感谢原创作者fengpinDBA的无私奉献
● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● QQ群:230161599 微信群:私聊
● 原文地址:http://blog.itpub.net/29339097/viewspace-1062090/
● 小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● QQ群: 230161599 微信群:私聊
● 联系我请加QQ好友(642808185),注明添加缘由
●【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】
...............................................................................................................................
手机长按下图识别二维码或微信客户端扫描下边的二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,免费学习最实用的数据库技术。
实例恢复
Oracle实例在非正常关闭或执行SHUTDOWN ABORT强制关闭后,实例在下次打开数据库之前会执行实例恢复过程,这个过程是由Oracle自动完成的。执行实例恢复的目的是确保数据的一致性,只有当联机Redo日志文件和UNDO表空间的介质没有被破坏才能确保实例恢复能够成功。
1. RAC的实例恢复
当软件、硬件或者人为问题导致实例失败之后,Oracle数据库自动使用联机Redo日志和UNDO数据执行实例恢复操作。
Crash恢复与实例恢复的区别:
l 一个单实例数据库或者RAC数据库所有实例失败之后,第一个打开数据库的实例会自动执行实例恢复。这种形式的实例恢复称为Crash恢复。
l 一个RAC数据库的一部分但不是所有实例失败后,在RAC中幸存的实例自动执行失败实例的恢复称为实例恢复。
根据Crash恢复和实例恢复的不同,由幸存实例或者第一个重启的实例读取失败实例生成的联机Redo日志和UNDO表空间数据,使用这些信息确保只有已提交的事务被写到数据库中,回滚在失败时候活动的事务,并释放事务使用的资源。
2. 实例恢复的阶段
在实例发生异常终止的情况下,数据库处于以下的状态:
l 事务提交的数据块只写入联机Redo日志中,没有更新到数据文件(那么未写入数据文件的更新必须重新写入数据文件)。
l 由于DBWR进程是异步向磁盘写入数据的,数据文件中可能包含没有被提交但已经写入数据文件的改变,这些改变必须回滚到之前的状态,以确保数据的一致性。
实例恢复利用联机Redo日志文件解决第一个问题,利用UNDO数据同步数据文件解决第二个问题,从而确保数据库数据的一致性。
因此,实例恢复过程会经历两个阶段:
u 实例恢复的第一个阶段称为Cache恢复或者前滚,确保联机Redo日志中所有已提交的事务操作的数据写回到数据文件中。如果正在执行的检查点还未完全执行完毕时发生实例失败,前滚过程可能需要通过多个联机Redo日志文件才能使数据恢复到之前时间的状态。前滚之后,数据中就包含了连接Redo日志文件中所有已提交的数据。在失败之前,数据文件中可能也包含未提交的改变,或者是记录在联机Redo日志中但未提交的数据,在前滚的时候被写到硬盘中。
u 实例恢复的第二个阶段称为回滚或者事务恢复,Oracle数据库应用UNDO块回滚在数据块中未提交的改变,这些数据块是在失败之前或者Cache恢复期间被写入的。回滚完成之后,整个实例恢复才算完成,而Redo和UNDO的丢失或者损坏都可能导致实例恢复失败。Oracle数据库能同时回滚多个事务。所有在失败的时候是活动的事务都被打上了终止的标记,等待SMON进程回滚终止的事务。
数据库由SMON后台进程自动应用联机Redo日志文件中的条目和读取UNDO表空间中的数据完成实例恢复。
Oracle介质恢复
介质恢复是基于物理备份恢复数据,介质恢复技术是Oracle数据库出现介质故障时恢复的重要保障。
1. 介质恢复的过程
介质恢复包括块恢复、数据文件恢复、表空间恢复和整个数据库的恢复。介质恢复主要是针对错误类型中的介质失败,如果是少量的块失败,可以使用介质恢复中的块恢复来快速修复;但如果是其它情况的丢失,根据具体情况,可使用数据文件恢复、表空间恢复甚至全库恢复。
介质恢复过程包括还原(RESTORE)和恢复(RECOVER)两个步骤:
还原是将某个时间点数据文件的拷贝再拷贝回去,还原后的数据库处于不一致性的状态,或不是最新的状态,还需要执行恢复操作。恢复就是使用归档Redo日志文件和联机Redo日志文件将不一致的数据库应用到一致性状态。如果是完全恢复,数据库就是最新的一致性状态;如果是不完全恢复,数据库是非最新的一致性状态。
| 注意:还原只是建立在数据库备份的基础版本上,例如,如果数据库备份包括0级备份和很多1级备份,还原只是应用0级备份,恢复过程会根据情况自动应用1级备份或Redo日志将数据库恢复到一致性的状态。 |
数据库的恢复过程又分为完全恢复和不完全恢复:
u 完全恢复
完全恢复是一种没有数据库丢失的恢复方式,能够恢复到最新的联机Redo日志中已提交的数据。在传统恢复方式中,因介质失败破坏了数据文件之后,可以在数据库、表空间和数据文件上执行完全介质恢复。
u 不完全恢复
不完全恢复是一种与完全恢复相反的恢复方式,是一种丢失数据的恢复方式,也称为数据库时间点恢复。通常情况下,若Flashback Database没有启用或者变得无效,可以执行不完全恢复撤销一个用户错误,不完全恢复不一定在原有的数据库环境执行,可以在测试环境下执行不完全恢复,将找回的数据再重新导入生产库中。对于不完全恢复来说,只能执行整个数据库的恢复,不能执行某个数据文件或表空间的不完全恢复。
不完全恢复根据备份情况恢复到与指定时间、日志序列号和SCN具有一致性的数据,之后的数据都将丢失。执行不完全恢复一方面是因为归档Redo日志、联机Redo日志的丢失不得不执行不完全恢复,另一方面可能是因为在某个时刻错误地操作了数据,过了一段时间之后才发现问题,而其它的恢复手段都无法恢复数据,这时也不得不使用不完全恢复来找回数据。
执行不完全恢复必须从备份中还原所有的数据文件,备份文件必须是要恢复的时间点之前创建的。当恢复完成,使用RESTLOGS选项打开数据库,将重新初始化联机Redo日志,创建一个新的日志序列号流,日志序列号从1开始,RESETLOGS之后的SCN还是在递增。
2. 物理坏块和逻辑坏块
Oracle数据文件的坏块可以分为物理坏块和逻辑坏块。物理坏块指的是块格式本身已经损坏,块内的数据没有任何意义。而逻辑坏块,指的是块内的数据在逻辑上存在问题,比如说索引块的索引值没有按从小到大排列导致的逻辑坏块。物理坏块一般是由于内存问题、OS问题、I/O子系统问题或硬件引起的,逻辑坏块一般是有Oracle bug等原因引起的。
各种各样的块损坏通常是通过Oracle的ORA-1578错误报告出来的,详细的损坏描述会在告警日志中打印出来。
l 物理块损坏
块的物理损坏有很多种情况,例如块头(Cache Header)被一个不正确的值替换、块被破坏或变得不完整、块的头和尾不匹配、块的校验和(CHECKSUM)不正确、块错位、块被归零。
n 破裂块
一个破裂块的意思即块是不完整的,块头的信息不能匹配块尾的信息。在告警日志中可能出现如下的日志信息:
Corrupt block relative dba:0x0380e573(file 14,block 58739)
Fractured block found during buffer read
……
n 不正确的校验和
块的校验和也是数据块的一致性检查的依据。块的一致性检查由DB_BLOCK_CHECKSUM和DB_BLOCK_CHECKING两个初始化参数控制。DB_BLOCK_CHECKSUM是一种物理检查,DB_CHECK_CHECKING是一种逻辑检查。
参数1 DB_CHECK_CHECKSUM
DB_BLOCK_CHECKSUM只有在写入(DBWn常规写或用户进程直接路径写入)时,根据一个CHECKSUM算法计算数据块的校验和,然后写入数据块的一个特定位置(CACHE HEADER,具体是以0字节算起,块的第16~17字节),在读取块时再进行检验。主要是防止I/O硬件和I/O子系统的错误。
CHECKSUM的算法只是根据块的字节值计算一个校验和,算法比较简单。该参数默认在所有表空间上都起作用。
DB_BLOCK_CHECKSUM参数属性
属性 |
描述 |
语法 |
DB_BLOCK_CHECKSUM={OFF|FALSE|TYPICAL|TURE|FULL} |
默认值 |
TYPICAL |
修改范围 |
ALTER SESSION,ALTER SYSTEM |
只有当参数值是TYPICAL或者FULL,并且块的最后一次写是存储了一个校验和时,读取这个块,校验和才会被验证。在FULL模式,Oracle用update/delete语句改变数据之前会验证校验和,改变被应用之后还会重新计算校验和。
从Oracle Database 11g开始,大多数日志校验和都是通过前台进程产生的,同时LGWR执行其余的工作,这是为了更好地发挥CPU和缓存的效率。当这个参数设置为FULL,写日志块到磁盘之前,LGWR验证通过前台进程生成的每个日志块的校验和。在Oracle Database 11g之前的版本中,LGWR独自执行日志块校验和。数据文件块的校验和是由DBWR进程负责计算和管理的。
这个参数设置为OFF时,DBWn只为SYSTEM表空间计算校验和,不为用户表空间计算校验和。另外,此时数据库也不会执行日志的校验工作。
校验和可以使Oracle数据库察觉到磁盘、存储系统或者I/O系统引起的损坏。如果设置为FULL,DB_BLOCK_CHECKSUM也会捕捉在内存中的损坏,并停止它们对磁盘的操作。设置这个参数为TYPICAL值只会引起系统额外的1%~2%的负载,设置为FULL会引起4%~5%的负载。Oracle推荐设置DB_BLOCK_CHECKSUM为TYPICAL。为了保持向后兼容性,TRUE和FALSE值被保留,TRUE等同于TYPICAL,FALSE等同于OFF。
如果DB_BLOCK_CHECKSUM不等于FALSE值,每次读取块,Oracle计算校验和,都与存储在块头中的校验和进行对比。如下例子:
Corrupt block relative dba: 0x0380a58f (file 14,block 42383)
Bad check value found during buffer read
……
参数2 DB_BLOCK_CHECKING
DB_BLOCK_CHECKING参数主要是用于数据块的逻辑一致检查,但只是在块内,不包括块间的逻辑检查。主要用于防止在内存中损坏或数据损坏。
无论该参数如何设置,对SYSTEM表空间来说,逻辑一致检查始终处于“打开”状态,在其他表空间该参数默认是关闭的。
DB_BLOCK_CHECKING参数的属性
参数值 |
含义 |
OFF或者FALSE |
对于用户表空间没有任何逻辑一致性检查工作 |
LOW |
块的内容在内存中改变之后,执行基本的块头检查,如UPDATE语句、INSERT语句、磁盘读或者在RAC中内部实例之间的块传递之后发生检查工作 |
MEDIUM |
除了索引以外的所有对象执行LOW检查和完全语义检查,由于索引能在遭遇损坏的情况下的重建,所以可以不考虑对它检查 |
FULL或者TRUE |
所有对象执行MEDIUM检查和完全语义检查 |
Oracle通过遍历在块中的数据来检查一个块,确保它在逻辑上手尾一致。根据系统负载和参数值,块检查通常一起1%~10%的负载。打开块检查,大量的UPDATE或者INSERT将造成更大负载,对于一个繁忙的系统,特别有大量插入或者更新操作的系统来说,性能影响是比较明显的。如果性能负载可以被接受,应该考虑设置DB_BLOCK_CHECKING为FULL。为了保持向后的兼容性,TURE和FALSE参数值同样可以使用,FALSE等同于OFF,TRUE等同于FULL。
如果启用DB_BLOCK_CHECKING参数,在磁盘的块发生逻辑损坏,下一次块更新将作为软损坏标记这个块,之后读取这个块产生ORA-1578的错误。
n 块错位
当Oracle察觉读取块的内容属于不同块但是校验和又是正确的时,会产生错误。
l 逻辑块损坏
若块包含一个正确的校验和,块头以下的结构是损坏的(块内容损坏),这可能引起不同的ORA-600错误。逻辑块损坏的详细损坏描述通常不会打印到告警日志。DBV将报告块具体的逻辑错误。
3. 坏块的检测工具
以下为损坏块的检测工具和使用方法:
l DBVERIRY坏块验证工具
DBVERIRY不能验证联机Redo日志、归档Redo日志、控制文件和RMAN备份集,只能用于数据文件的块验证。
n DBV验证传统数据文件
下面是使用DBV工具验证数据文件块的例子:
$ dbv file=/testdb/test01.dbf blocksize=8192
注意:DBV工具除了用于检测数据文件是否有坏块外,也用于获得坏块的详细信息。
n DBV验证裸设备数据文件
DBV要求file后面跟的必须是一个包含扩展名的文件,所以如果数据库使用裸设备作为存储方式,就必须使用ln命令连接裸设备一个带扩展名的文件,然后使用DBV工具通过对链接文件的验证实现对裸设备数据文件的验证。
n DBV验证ASM存储的数据文件
如果是验证存储在ASM中的数据文件则需要指定用户名和密码,如果不指定用户名和密码,将收到DBV-00008:USERID must bu specified for OSM files的报错。下面是使用DBV工具验证存储在ASM中的数据文件的块的例子:
$ dbv file=+DATAFILE/testdb/datafile/test.234.648839 userid=sys/oracle
l ANALYZE命令
Analyze命令的主要目的是通过分析数据库对象,为优化器收集数据库对象的统计量信息,以便优化器生成准确的执行计划。同时,它也能检查某个表或索引是否存在损坏的情况。Analyze执行坏块检查,但是不会标记坏块为corrupt,检测结果保存在USER_DUMP_DEST目录下的用户trace文件中。Analyze语法:
Analyze table/index / validate structure ;
Analyze命令会验证每个数据块、每条记录和索引的完整性。CASCADE关键字表示验证表及其相关的所有索引。与DBVERIFY不同的是,analyze只验证高水位线以下的数据块,analyze不会对未使用的空间进行验证。
SQL> analyze table fengpin.test validate structure;
l RMAN工具
RMAN是一块备份工具,就像一个过滤器,RMAN需要通过缓存过滤每一个块,其中一个特点就是检查块是否被损坏。如果备份的数据库中包含有坏块,将会收到错误
l EXP工具
对于包含坏块的表执行导出操作,会收到相关的错误信息。对于这种情况,在非归档模式无法通过块恢复修复块的情况下,有如下两种处理方法:
方法1:启用10231事件
通过设置10231诊断事件可以在导出的时候让Oracle忽略表损坏的块,10231是Oracle的内部诊断事件,设置在全表扫描时跳过坏块的数据块,只导出包含正确块的数据,之后把表删除,再把导出的表数据导入新表,从而修复该表。
1) 启用10231诊断事件
SQL> alter system set events=’10231 trace name context forever,level 10’;
2) 禁用10231诊断事件:
SQL> alter system set events=’10231 trace name context forever,level 0’;
方法2:使用DBMS_REPAIR包标记损坏的块。
可以使用DBMS_REPAIR包标记损坏的数据库对象,这样在对损坏的对象执行全表扫描的时候会跳过损坏的块。语法如下:
SQL> exec dbms_repair.skip_corrupt_blocks(‘’,’tablename’);
EXP坏块检查有一定的局限性,不会发现如下类型的坏块:
ü HWM(高水位线)以上的坏块
ü 索引中存在的坏块
ü 数据字典中存在的坏块
l Expdp工具
使用expdp工具不会给出坏块的提示,只会将对象正确的数据导出。
4. 块的损坏与恢复
块已经不是Oracle的格式,或者其内部是不一致的,那么这个块就被认为已损坏。块介质恢复是当数据文件是联机时,还原和恢复数据块的技术。如果只有一些块被破坏,那么块介质恢复是较好的恢复选择。
BBED(Block Brower and EDitor)是Oracle的一款内部工具,可以用来直接查看和修改Oracle数据文件块的内容。BBED是一个针对Oracle的二进制编译工具。该工具不受Oracle支持,默认是不生成可执行文件的,在使用钱需要重新编译。
1) 编译BBED
直接在Oracle 11gR2 的环境中编译BBED,将收到以下错误信息:
$ cd $ORACLE_HOME/rdbms/lib
$ make –f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
……
gcc: /u01/app/oracle/11.2.0/db_1/rdbms/lib/ssbbded.o: No such file or directory
gcc: /u01/app/oracle/11.2.0/db_1/rdbms/lib/sbbdpt.o: No such file or directory
Oracle 11gR2 环境中编译BBED可执行文件所需要的ssbbded.o和sbbdpt.o对象文件被移除,不过可以从Oracle 10g环境中将这两个文件拷贝到Oracle 11g环境中进行编译。
除了将上面的ssbbded.o和sbbdpt.o文件拷贝到Oracle 11g环境外,BBED还需要用到$ORACLE_HOME/rdbms/mesg目录下的bbedus.msg和bbedus.msb两个信息文件,这几个文件都需要从Oracle 10g中拷贝到Oracle 11g中对应的目录中。下面是将以上4个文件从Oracle 10g中拷贝到Oracle 11g对应目录之后的编译过程:
$ cd $ORACLE_HOME/rdbms/lib
$ make –f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
$ file bbed
$ size bbed
$ ldd bbed
$ cp bbed $ORACLE_HOME/bin/
$ cd /
$ which bbed
/u01/app/oracle/product/11.2.0/db_1/bin/bbed
编译成功后登录BBED,登录时需要密码(默认密码是:blockedit)
$ bbed
2) BBED模拟表数据块的损坏
a. 创建测试表
SQL> create table test.testbbed as select * from dba_tables;
b. 创建BBED参数文件
由于BBED无法对ASM进行操作,所以这里将表创建到ACFS文件系统的存储设备上。这里创建两个BBED参数文件,filelist.txt保存要操作的数据文件的ID和路径,bbed.par保存数据文件的块大小、filelist.txt的位置和操作模式:
$ more filelist.txt
6 /testbbed/tbtbs01.dbf
$ more bbed.par
blocksize=8192
listfile=filelist.txt
mode=edit
filelist.txt的内容可通过select file_id,file_name from dba_data_filesSQL查询得到。
c. BBED基本操作
ü 使用指定的参数文件登录BBED:
$ bbed parfile=bbed.par
ü 显示BBED配置文件中指定的数据文件信息:
BBED> info
ü 设置要操作的数据文件:
BBED> set file 6
ü 显示要操作的数据文件的详细信息:
BBED> show
d. 模拟坏块
修改文件号为6的第136号块:
BBED> modify 1000 file 6 block 136
如果修改错误,可以执行revert命令回滚。
e. 验证坏块
在BBED执行以下命令验证数据块,发现block 136已经损坏
BBED> verify
f. 使用DBV工具验证
使用DBV工具验证发现file 6 block 136已经损坏
$ dbv file=/testbbed/tbtbs01.dbf blocksize=8192
g. 执行块读取操作
执行一个test.testbbed的全表扫描,收到ORA-01578错误
SQL> alter system flush buffer_cache;
SQL> select /*+FULL(T)*/ COUNT(1) FROM TEST.TESTBBED T;
3) RMAN的块恢复
块介质恢复用来恢复一个单独的块或者数据文件中数据块的集合,如果是小数据量的数据丢失或损坏,而不是整个数据文件,这种类型的恢复是很有用的。通常,块损坏会在跟踪文件中报告错误信息。
块级别的数据丢失通常是由以下两个原因造成的:
n I/O错误引起的镜像数据丢失。
n 内存损坏,刷新到磁盘。
a. 使用RMAN BLOCKRECOVER命令的注意事项
n 目标数据库必须在MOUNT或者OPEN状态,如果执行某个数据文件的块介质恢复,那么该数据文件不能是脱机状态。
n 块介质恢复不支持基于时间点的块恢复。
n 只能在损坏的块上执行块介质恢复。
n 块被标记为介质损坏之后是不能访问的,直达恢复完成。
n 当使用备份的控制文件加载数据库时,不能执行块的介质恢复。
n 必须有一个包含损坏块文件的全备份,块介质恢复不能使用增量备份。
n 如果RMAN访问块介质恢复需要特定归档Redo日志文件失败,那么将执行还原FAILOVER,尝试使用RMAN资料库中列出的适合这个操作的所有其它备份,如果没有合适的备份存在执行才会失败。
n 数据文件头不能被恢复
n 不能在非归档模式下执行块介质恢复。
b. RMAN BLOCKRECOVER命令的使用方式
RMAN BLOCKRECOVER命令有以下三种使用方式:
方式1 使用BLOCKRECOVER CORRUPTION LIST命令恢复在V$DATABASE_BLOCK_CORRUPTION视图中报告的所有块:
RMAN> blockrecover corruption list;
方式2 使用BLOCKRECOVER 命令的时候指定文件号和块号:
RMAN> blockrecover datafile block ;
方式3 执行blockrecover命令的时候指定表空间和数据块地址(DBA):
RMAN> blockrecover tablespace DBA ;
c. RMAN BLOCKRECOVER使用的例子
例子1 恢复3个数据文件的损坏块:
RMAN> BLOCKRECOVER DATAFILE 2 BLOCK 12,13 DATAFILE 3 BLOCK 5,98,99 DATAFILE 4 BLOCK 19;
例子2:从数据文件拷贝中还原、恢复一系列块:
RMAN> RUN
{
BLOCKRECOVER DATAFILE 3 BLOCK 2,3,4,5 TABLESPACE sales DBA 4194405,4194409,4194412 from DATAFILECOPY;
}
例子3:从指定的tag备份总还原、恢复块
RMAN> BLOCKRECOVER TABLESPACE SYSTEM DBA 4194404,4194405 FROM TAG “weekly_backup”;
例子4:从用于恢复数据到两天以前的备份中还原、恢复SYSTEM表空间中的两个块:
RMAN> BLOCKRECOVER TALBESPACE SYSTEM DBA 4194404,4194405 RESOTRE UNTILL TIME ‘sysdate-2’;
例子5:运行备份验证数据库,修复在V$DATABASE_BLOCK_CORRUPTION中记录的所有损坏块:
RMAN> BACKUP VALIDATE DATABASE;
RMAN> BLOCKRECOVER CORRUPTION LIST;
4) 确定损坏块对应的对象
要确定一个损坏的对象需要知道AFN(Absolute File Numbe,绝对文件号)和BL(Block Number,块号)。AFN和RFN(Relative File Number,相对文件号)通常是相同的,但是也可能不同(特别是如果数据库从Oracle7迁移或者如果使用的是可传输、可插拔的表空间),获得正确的AFN和RFN就显得非常重要,如果指定了错误的AFN将导致找不到对象或错误识别对象。
a. 确定AFN和BL
方法1:从ORA-1578得到AFN
ORA-1578之后产生的ORA-1110错误提供AFN号码。
方法2:从DBVERIFY输出获得AFN。
通过使用DBV工具会报告损坏的块,DBV工具通过提供与相关的RDBA、RFN和BL信息。
方法3:从RMAN获得AFN
RMAN在V$DATABASE_BLOCK_CORRUPTION视图报告损坏的块。该视图的字段FILE#表示AFN,字段BLOCK#表示BL。
b. 定位损坏的对象
一旦AFN被识别,执行以下SQL语句定位损坏的对象:
SQL> select *
From DBA_EXTENTS
Where file_id=&AFN
And &BL BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS-1;
如果损坏的块是数据文件开头,这将导致数据库无法正常启动和关闭,并且使用RMAN BLOCKRECOVER也不能恢复。因此此时就要进行完全恢复或者尝试使用BBED修改块头。
1) 模拟损坏数据文件头的块
使用BBED方法将数据文件6的第1个块损坏,DBV的检查结果如下:
$ dbv file=/test/test01.dbf
2) 尝试使用RMAN BLOCKRECOVER进行恢复
执行以下命令使用RMAN的BLOCKRECOVER对数据文件6的第1个块进行恢复:
RMAN> blockrecover datafile 6 block 1;
Starting recover as 2013-12-07 16:24
Using channel ORA_DISK_1
Starting media recovery
Media recovery complete,elapsed time: 00:00:00
Finished recover at 2013-12-07 16:24
恢复显示是完成的,也没有报错。但是执行DBV验证命令发现标记的坏块还是两个,及没有真正修复。说明使用RMAN BLOCKRECOVER对数据文件头的修复是没有作用的。
尝试正常关闭数据库,由于数据库无法完成检查点工作,所以正常关闭操作失败:
SQL> shutdown immediate
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: ‘/test/test01.dbf’
ORA-01210: data file header is media corrupt
强制关闭数据库:
SQL> shutdown abort
重启数据库,发现数据库无法打开数据文件:
SQL> startup
……
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: ‘/test/test01.dbf’
ORA-01210: data file header is media corrupt
3) 执行数据文件的完全恢复
执行以下命令还原、恢复6号数据文件:
RMAN> restore datafile 6;
RMAN> recover datafile 6;
尝试打开数据库:
SQL> alter database open;
Database altered.
Oracle数据库中有各种各样的块,如空块、表头块、数据块、索引块、数据文件头块、UNDO段块等。如果损坏的是普通表的数据块,那即不会影响启动数据库,也不会影响其他表的正常访问,只是在访问该表的时候会出现问题。如果损坏的是数据文件的块头,那么将导致数据库无法正常启动和停止,执行块恢复不能修复这个问题,执行数据文件的完全恢复才能恢复数据文件块头的损坏或尝试使用BBED修改数据文件块头。
不完全恢复又称为数据库基于时间点恢复,是将整个数据库恢复到之前的某个时间点、日志序列号或者SCN号。如下不完全恢复的选项:
不完全恢复的选项
不完全恢复方式 |
RMAN选项 |
用户管理备份选项 |
恢复到某个时间点 |
until time |
until time |
恢复到某个日志序列号 |
until suquence |
until cancel |
恢复到某个SCN号 |
until SCN |
until change |
不完全恢复只能针对整个数据库而言,并不能执行数据文件和表空间的不完全恢复;另外,对于非归档模式的恢复来说,也不能执行不完全恢复。
1) 基于时间点的不完全恢复
RMAN> run {
shutdown immediate;
startup mount;
SQL “alter session set nls_date_format=’’YYYY-MM-DD HH24:MI:SS’’”;(两个单引号之间没有空格)
set until time ‘2013-12-07 17:24:00’;
restore database;
recover database;
alter database open resetlogs;}
SET UNTIL TIME时间可以使用多种表示方式,可以使用TO_DATE函数来表示时间,还可以使用SYSDATE-1方式来表示时间。
注意:不完全恢复是针对整个数据而言,如果在上面的脚本中,还原和恢复的是某个数据文件或表空间,那么脚本将忽略set until time设置,对数据文件或表空间进行完全恢复。对RESTORE命令指定until time或者until scn的意义在于这样可以自动选择最近的RMAN备份来恢复数据,以上的批量命令相当于为RESTORE和RECOVER都指定了until time子句,这样比单命令模式更加简单和合理。基于时间点的恢复不能恢复到最终备份完成时间点以前的时段。
2) 基于序列号的不完全恢复
基于序列号的不完全恢复须指定某个Redo线程的序列号,那么在这个序列号切换时间点之前的所有实例的归档日志都需要的,每个节点的负载不同,其他实例的序列号可能比指定的Redo线程序列号要大。
以下是在RMAN中基于日志序列号的不完全恢复的例子:
RMAN> run {
Shutdown immediate;
Startup mount;
Set until sequence 10350 thread 1;
Restore database;
Recover database;
Alter database open resetlogs;}
注意:指定线程序列号为10350,但是恢复是不包含该序列号的日志的,也就是说恢复只会恢复到thread 1 sequence 10304的日志,时间点和scn恢复同样如此。
3) 基于SCN的不完全恢复
下面是在RMAN中基于SCN的不完全恢复的例子:
RMAN> run {
shutdown immediate;
startup mount;
set until scn 324394;
restore database;
recover database;
alter database open resetlogs;}
注意:对打开的数据库执行的全库备份或者0级备份,即使不完全恢复到执行全库备份或者0级备份的备份时间点也可能需要部分Redo日志,原因在于对打开的数据库执行RMAN备份是一个不一致的备份。
表空间时间点恢复(Tablespace Point-in-time Recovery,TSPITR)特性可以恢复一个或更多的表空间早于数据库其他部分的某个时间点。表空间时间点恢复是表空间的不完全恢复,操作起来比较复杂。
表空间时间点恢复能在不影响数据库其它表空间和对象的情况下,恢复一个或更多的用户表空间到之前的某个时间点。表空间时间点恢复是对某个表空间执行基于某个时间点的恢复,是特殊的不完全恢复。RMAN TSPITR可以用于以下场景:
n 一个不正确的job或者DML语句破坏了数据库其中一个表空间的数据,RMAN TSPITR可用于被破坏表空间的恢复。
n DDL操作改变了表的结构之后,RMAN TSPITR可用于丢失数据的恢复。这种情况不能使用Flashback Table找回表之前的结构的数据,如表结构变化后的一个TRUNCATE表操作。
n 一个表被一个drop语句加了purge选项彻底drop。RMAN TSPITR可用于这种情况的恢复。
n 恢复drop的表空间,当没有使用恢复目录,RMAN能对被drop的表空间执行TSPITR。
n 从一个表的逻辑损坏中恢复。
表空间时间点恢复和Flashback有点类似,在没有介质失败的情况下,数据也可以使用Flashback Database找回,但是Flashback Database会导致整个数据库被闪回到之前的某个时间点。与TSPITR不同的是,Flashback Database特性必须产生Flashback日志,使用Flashback Database闪回数据库比使用TSPITR有更多的限制,TSPITR可以扩展到能找回可用于恢复的更早备份数据。
1) TSPITR的工作原理
TSPITR工作原理的5个步骤:
步骤1 在辅助实例上用目标数据库的备份集还原数据文件。
步骤2 在辅助实例上用目标数据库的归档文件恢复数据文件。
步骤3 在辅助数据库上导出相关数据。
步骤4 修改主库的控制文件。
步骤5 将辅助数据上导出的文件导入目标数据库。
2) RMAN TSPITR模式
表空间时间点恢复使用的是RMAN的RECOVER tablespace命令,执行RMAN TSPITR有几个选项,不同的选项协调各种不同的操作模式之间对特定环境的自动化操作。
a. 全自动化(默认方式)
在这种模式下,RMAN管理整个TSPITR过程。制定表空间的恢复集、辅助目的地、目标时间和允许RMAN管理所有TSPITR的其它方面。
b. 自动化
可以覆盖一些默认RMAN TSPITR设置,但仍然使用RMAN管理辅助实例和辅助目的地。这是默认方式的变种,RMAN TSPITR提供一些固定管理的同事允许手动指定一些参数,主要包含以下两个参数:
n 辅助集或恢复集文件的位置
n 初始化参数文件
除了在TSPITR之后的恢复集文件位置,在TSPITR期间的辅助集文件、通道设置和参数或辅助实例的其它方面等更多控制都推荐使用默认方式。全自动和自动化都是使用RMAN自动管理辅助实例。
c. 非自动化
使用这种模式是手动创建和管理辅助实例的所有方面和一部分TSPITR过程。当必须分配不同的通道或者使用用户管理辅助实例改变参数时,使用这种模式是合适的。
3) 执行全自动化的TSPITR
下面以默认的全自动化模式在目标数据库服务器创建辅助数据库构建TSPITR,恢复在目标数据库对表的一个误操作。目标数据库与辅助数据库都在一台服务器上,下表是两个数据库的实例名和数据库名称对照表:
数据库类型 |
实例名称 |
数据库名称 |
目标数据库 |
test |
test |
辅助数据库 |
test2 |
test |
a. 创建模拟环境
步骤1 在目标数据创建测试表空间xy_tbs:
SQL> create tablespace xy_tbs datafile ‘/u01/app/oracle/test/xy_tbs01.dbf’ size 5M;
步骤2 确保目标数据库处在归档模式,使用RMAN查找出xy_tbs表空间的file_id,对它进行备份:
RMAN> report schema;
……
RMAN> backup datafile 5;
步骤3 创建测试用户xiaoyang:
SQL> create user xiaoyang identified by xiaoyang default tablespace xy_tbs tempory tablespace temp;
SQL> grant create session,create table,unlimited tablespace to xiaoyang;
SQL> connect xiaoyang/xiaoyang;
步骤4 创建两个测试表:x1和x2,每个表插入一条测试数据:
SQL> create table x1(D date);
SQL> create table x2(D2 date);
SQL> insert into x1 values(sysdate);
SQL> insert into x2 values(sysdate);
SQL> commit;
步骤5 查看当前时间作为表空间的恢复时间点:
SQL> alter session set nls_date_format=’YYYY-MM-DD HH24:MI:SS’;
SQL> select sysdate from dual;
步骤6 在恢复时间点之后向x2表中插入一条数据和创建一个新表x3,向x3插入一条测试数据:
SQL> insert into x2 values(sysdate);
SQL> create table x3(D3 date);
SQL> insert into x3 values(sysdate);
SQL> commit;
步骤7 手动drop掉表x1:
SQL> drop table x1 purge;
假设drop x1表是一个误操作,现在要通过TSPITR恢复技术恢复该表。
b. 检查表空间是否自关联
执行以下SQL语句检查表空间自关联情况:
SQL> execute dbms_tts.transport_set_check(‘xy_tbs’,true,true);
SQL> select * from transport_set_violations;
如果查询transport_set_violations视图有值返回,说明表空间有自关联,需要手动处理提示的问题。
c. 标识TSPITR之后将会丢失的对象
步骤1 通过时间标识TSPITR之后将会丢失的对象:
SQL> select owner,name,tablespace_name,to_char(creation_time,’YYYY-MM-DD HH24:MI:SS’) from ts_pitr_objects_to_be_dropped where tablespace_name in(‘xy_tbs’) and creation_time > to_date(‘2013-12-08 09:43:00’,’YYYY-MM-DD HH24:MI:SS’) order by tablespace_name,creation_time;
步骤2 通过SCN标识TSPITR之后将会丢失的对象:
SQL> select owner,names,tablespace_name,to_char(creation_time,’YYYY-MM-DD HH24:MI:SS’) from ts_pitr_objects_to_be_dropped where tablespace_name in(‘xy_tbs’) and creation_time > to_date(to_char(scn_to_timestamp(1638492),’YYYY-MM-DD HH24:MI:SS’),’YYYY-MM-DD HH24:MI:SS’) order by tablespace_name,creation_time;
如果以上两个查询有结果返回,那么在执行TSPITR之前应该先将这些对象进行逻辑备份,TSPITR完成之后,再将这些对象以替换的方式导入,以恢复产生数据丢失的对象。
d. 创建辅助数据库参数文件
转储目标数据库参数文件,将该参数文件拷贝到$ORACLE_HOME目录,重命名为inittest2.ora,参考如下参数文件内容调整inittest2.ora实例的初始化参数文件:
*.audit_file_dest=’/u01/app/oracle/admin/test2/adump’
*.control_files=’/u01/app/oracle/oradata/test2/control01.ctl’
……
db_file_name_convert=(“/u01/app/oracle/oradata/test”,”/u01/app/oracle/oradata/test2”)
log_file_name_convert=(“/u01/app/oracle/oradata/test”,”/u01/app/oracle/oradata/test2”)
log_archive_start=false
lock_name_space=test2
修改test2实例初始化参数文件中的audit_file_dest、control_file参数,确保与原有数据库的存储位置不同。添加db_file_name_convert、log_file_name_convert、log_archive_start和lock_name_space参数设置。
e. 创建目录结构
根据实例test2参数的设置创建相应的目录结构:
$ mkdir –p /u01/app/oracle/admin/test2/adump
$ mkdir –p /u01/app/oracle/oradata/test2
f. 创建test2实例密码文件
$ cd $ORACLE_HOME/dbs/
$ orapwd file=orapwtest2 password=oracle entries=5
g. 创建辅助数据库实例的静态注册
在grid用户下的$GRID_HOME/network/admin/listener.ora文件中修改如下配置:
$ cat listener.ora
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = test2)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1)
(SID_NAME = test2)
)
)
h. 添加Oracle Net本地服务名
在Oracle用户下的$ORACLE_HOME/network/admin/tnsnames.ora文件中添加如下配置:
TEST2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rhel2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test2)
)
)
i. 启动辅助数据库到NOMOUNT状态
$ export ORACLE_SID=test2
$ sqlplus / as sysdba
SQL> create spfile from pfile;
SQL> startup nomount
j. 执行TSPITR恢复
使用RMAN同时连接到目标数据库和辅助数据库,使用RECOVER TABLESPACE命令执行TSPITR操作:
$ rman target /
RMAN> connect auxiliary sys/oracle@test2
RMAN> run {
allocate auxiliary channel a1 type disk;
allocate channel c1 type disk;
recover tablespace xy_tbs until time “to_date(‘2013-12-08 09:30:00’,’YYYY-MM-DD HH24:MI:SS’)”;
release channel c1;
}
执行TSPITR需要手动分配auxiliary通道
使目标数据中xy_tbs表空间ONLINE:
SQL> alter tablespace xy_tbs online;
k. 验证恢复结果
SQL> select * from xiaoyang.x1;
SQL> select * from xiaoyang.x2;
SQL> select * from xiaoyang.x3;
对于正常关闭的数据库来说,关闭前会执行一个检查点以保证数据库的一致性,重启之后,联机日志是是否存在都不会导致数据的丢失。然而,如果是非正常关闭的数据库,重启之后会执行实例恢复的过程,如果实例恢复过程需要的UNDO活Redo日志丢失,那么就可能造成数据的不一致和数据的丢失。
a. 连接Redo日志损坏的4种情况
联机Redo日志文件的损坏有以下4中情况:
情况1 非当前日志损坏,正常关闭数据库。
情况2 非当前日志损坏,非正常关闭数据库。
情况3 当前日志损坏,正常关闭数据库。
情况4 当前日志损坏,非正常关闭数据库。
b. 处理方法
1) 情况1和情况2的处理方法
情况1和情况2的处理方法一样,直接把日志文件清除即可:
SQL> alter database clear logfile group 3;
2) 情况3的处理方法
在SQLPLUS中执行以下的SQL语句以RESETLOGS模式重新打开数据库:
SQL> startup mount;
SQL> recover database until cancel;
SQL> alter database open resetlogs;
3) 情况4的处理方法
这种情况会导致联机Redo日志中的一部分已提交的数据丢失,实例恢复中的前滚操作不能成功执行,回滚操作也无法执行,这也会导致部分数据的丢失。处理方法是强制打开数据库或通过备份执行介质不完全恢复。
数据库的脱机包括数据文件的脱机和表空间的脱机,数据文件的脱机和表空间非正常脱机在下一次执行联机命令之前都无需先执行介质恢复操作,介质恢复成功才能联机成功。
数据文件添加到表空间之后不能再被删除,也没有语法支持这么做,如果不想使用该数据文件,唯一的方法是将数据文件设置为OFFLINE状态。执行以下步骤将数据文件设置为OFFLINE状态:
1) 如果是归档模式可以执行如下SQL语句设置数据文件的状态为OFFLINE:
SQL> alter database datafile ‘xxx.dbf’ offline;
2) 如果是非归档模式执行以下SQL语句将数据文件状态设置为OFFLINE:
SQL> alter database datafile ‘xxx.dbf’ offile drop;
即使数据文件脱机,数据文件相关的数据字典信息、元数据信息依然存在,当表空间被删除后,相关数据文件的信息才会被清除。Drop tablespace只是清空Oracle数据字典信息,即使数据文件不存在也可以正常的drop表空间。对于数据文件的脱机,在设置该数据文件OFFLINE的时候都需要对该数据文件执行介质恢复。
如果在非归档模式下使用OFFLINE drop使数据文件脱机,这就意味着该数据文件可能无法再恢复到online状态,原因在于非归档模式下可能没有足够的日志文件在执行online的时候完成介质恢复。如果数据文件脱机之后日志没有发生切换,所有需要的日志还依然存在的话,那么非归档模式下数据文件的脱机也可以再次变成online状态。
表空间脱机实际就是表空间对应的所有数据文件脱机。
表空间脱机分为正常脱机、临时脱机和立即脱机,如下:
1) 正常脱机
这是默认的选项,如果表空间正常脱机,当重新执行online的时候,Oracle会用相应的SCN来更新表空间数据文件头SCN即可正常地online表空间,而不需要执行介质恢复。执行以下SQL语句是表空间正常脱机:
SQL> alter tablespace xxx offline;
2) 临时脱机
当执行临时脱机(OFFLINE temporary)语句之前已经有表空间对应的数据文件脱机,那么在是表空间重新online之前需要执行特定数据文件的介质恢复。执行以下的SQL语句是表空间临时脱机:
SQL> alter tablespace xxx offline temporary;
3) 立即脱机
执行这个操作(OFFLINE immediate)表示立即使表空间脱机,在下次使表空间online的时候必须执行介质恢复,介质恢复成功之后表空间才能变成online状态。执行以下的SQL语句是表空间立即脱机:
SQL> alter tablespace xxx offline immediate;
...............................................................................................................................
● 本文来自于itpub转载文章,若有侵权,请联系小麦苗及时删除,非常感谢原创作者fengpinDBA的无私奉献
● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● QQ群:230161599 微信群:私聊
● 原文地址:http://blog.itpub.net/29339097/viewspace-1062090/
● 小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● QQ群: 230161599 微信群:私聊
● 联系我请加QQ好友(642808185),注明添加缘由
●【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】
...............................................................................................................................
手机长按下图识别二维码或微信客户端扫描下边的二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,免费学习最实用的数据库技术。
4. 块的损坏与恢复
块已经不是Oracle的格式,或者其内部是不一致的,那么这个块就被认为已损坏。块介质恢复是当数据文件是联机时,还原和恢复数据块的技术。如果只有一些块被破坏,那么块介质恢复是较好的恢复选择。
BBED(Block Brower and EDitor)是Oracle的一款内部工具,可以用来直接查看和修改Oracle数据文件块的内容。BBED是一个针对Oracle的二进制编译工具。该工具不受Oracle支持,默认是不生成可执行文件的,在使用钱需要重新编译。
1) 编译BBED
直接在Oracle 11gR2 的环境中编译BBED,将收到以下错误信息:
$ cd $ORACLE_HOME/rdbms/lib
$ make –f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
……
gcc: /u01/app/oracle/11.2.0/db_1/rdbms/lib/ssbbded.o: No such file or directory
gcc: /u01/app/oracle/11.2.0/db_1/rdbms/lib/sbbdpt.o: No such file or directory
Oracle 11gR2 环境中编译BBED可执行文件所需要的ssbbded.o和sbbdpt.o对象文件被移除,不过可以从Oracle 10g环境中将这两个文件拷贝到Oracle 11g环境中进行编译。
除了将上面的ssbbded.o和sbbdpt.o文件拷贝到Oracle 11g环境外,BBED还需要用到$ORACLE_HOME/rdbms/mesg目录下的bbedus.msg和bbedus.msb两个信息文件,这几个文件都需要从Oracle 10g中拷贝到Oracle 11g中对应的目录中。下面是将以上4个文件从Oracle 10g中拷贝到Oracle 11g对应目录之后的编译过程:
$ cd $ORACLE_HOME/rdbms/lib
$ make –f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
$ file bbed
$ size bbed
$ ldd bbed
$ cp bbed $ORACLE_HOME/bin/
$ cd /
$ which bbed
/u01/app/oracle/product/11.2.0/db_1/bin/bbed
编译成功后登录BBED,登录时需要密码(默认密码是:blockedit)
$ bbed
2) BBED模拟表数据块的损坏
a. 创建测试表
SQL> create table test.testbbed as select * from dba_tables;
b. 创建BBED参数文件
由于BBED无法对ASM进行操作,所以这里将表创建到ACFS文件系统的存储设备上。这里创建两个BBED参数文件,filelist.txt保存要操作的数据文件的ID和路径,bbed.par保存数据文件的块大小、filelist.txt的位置和操作模式:
$ more filelist.txt
6 /testbbed/tbtbs01.dbf
$ more bbed.par
blocksize=8192
listfile=filelist.txt
mode=edit
filelist.txt的内容可通过select file_id,file_name from dba_data_filesSQL查询得到。
c. BBED基本操作
ü 使用指定的参数文件登录BBED:
$ bbed parfile=bbed.par
ü 显示BBED配置文件中指定的数据文件信息:
BBED> info
ü 设置要操作的数据文件:
BBED> set file 6
ü 显示要操作的数据文件的详细信息:
BBED> show
d. 模拟坏块
修改文件号为6的第136号块:
BBED> modify 1000 file 6 block 136
如果修改错误,可以执行revert命令回滚。
e. 验证坏块
在BBED执行以下命令验证数据块,发现block 136已经损坏
BBED> verify
f. 使用DBV工具验证
使用DBV工具验证发现file 6 block 136已经损坏
$ dbv file=/testbbed/tbtbs01.dbf blocksize=8192
g. 执行块读取操作
执行一个test.testbbed的全表扫描,收到ORA-01578错误
SQL> alter system flush buffer_cache;
SQL> select /*+FULL(T)*/ COUNT(1) FROM TEST.TESTBBED T;
3) RMAN的块恢复
块介质恢复用来恢复一个单独的块或者数据文件中数据块的集合,如果是小数据量的数据丢失或损坏,而不是整个数据文件,这种类型的恢复是很有用的。通常,块损坏会在跟踪文件中报告错误信息。
块级别的数据丢失通常是由以下两个原因造成的:
n I/O错误引起的镜像数据丢失。
n 内存损坏,刷新到磁盘。
a. 使用RMAN BLOCKRECOVER命令的注意事项
n 目标数据库必须在MOUNT或者OPEN状态,如果执行某个数据文件的块介质恢复,那么该数据文件不能是脱机状态。
n 块介质恢复不支持基于时间点的块恢复。
n 只能在损坏的块上执行块介质恢复。
n 块被标记为介质损坏之后是不能访问的,直达恢复完成。
n 当使用备份的控制文件加载数据库时,不能执行块的介质恢复。
n 必须有一个包含损坏块文件的全备份,块介质恢复不能使用增量备份。
n 如果RMAN访问块介质恢复需要特定归档Redo日志文件失败,那么将执行还原FAILOVER,尝试使用RMAN资料库中列出的适合这个操作的所有其它备份,如果没有合适的备份存在执行才会失败。
n 数据文件头不能被恢复
n 不能在非归档模式下执行块介质恢复。
b. RMAN BLOCKRECOVER命令的使用方式
RMAN BLOCKRECOVER命令有以下三种使用方式:
方式1 使用BLOCKRECOVER CORRUPTION LIST命令恢复在V$DATABASE_BLOCK_CORRUPTION视图中报告的所有块:
RMAN> blockrecover corruption list;
方式2 使用BLOCKRECOVER 命令的时候指定文件号和块号:
RMAN> blockrecover datafile block ;
方式3 执行blockrecover命令的时候指定表空间和数据块地址(DBA):
RMAN> blockrecover tablespace DBA ;
c. RMAN BLOCKRECOVER使用的例子
例子1 恢复3个数据文件的损坏块:
RMAN> BLOCKRECOVER DATAFILE 2 BLOCK 12,13 DATAFILE 3 BLOCK 5,98,99 DATAFILE 4 BLOCK 19;
例子2:从数据文件拷贝中还原、恢复一系列块:
RMAN> RUN
{
BLOCKRECOVER DATAFILE 3 BLOCK 2,3,4,5 TABLESPACE sales DBA 4194405,4194409,4194412 from DATAFILECOPY;
}
例子3:从指定的tag备份总还原、恢复块
RMAN> BLOCKRECOVER TABLESPACE SYSTEM DBA 4194404,4194405 FROM TAG “weekly_backup”;
例子4:从用于恢复数据到两天以前的备份中还原、恢复SYSTEM表空间中的两个块:
RMAN> BLOCKRECOVER TALBESPACE SYSTEM DBA 4194404,4194405 RESOTRE UNTILL TIME ‘sysdate-2’;
例子5:运行备份验证数据库,修复在V$DATABASE_BLOCK_CORRUPTION中记录的所有损坏块:
RMAN> BACKUP VALIDATE DATABASE;
RMAN> BLOCKRECOVER CORRUPTION LIST;
4) 确定损坏块对应的对象
要确定一个损坏的对象需要知道AFN(Absolute File Numbe,绝对文件号)和BL(Block Number,块号)。AFN和RFN(Relative File Number,相对文件号)通常是相同的,但是也可能不同(特别是如果数据库从Oracle7迁移或者如果使用的是可传输、可插拔的表空间),获得正确的AFN和RFN就显得非常重要,如果指定了错误的AFN将导致找不到对象或错误识别对象。
a. 确定AFN和BL
方法1:从ORA-1578得到AFN
ORA-1578之后产生的ORA-1110错误提供AFN号码。
方法2:从DBVERIFY输出获得AFN。
通过使用DBV工具会报告损坏的块,DBV工具通过提供与相关的RDBA、RFN和BL信息。
方法3:从RMAN获得AFN
RMAN在V$DATABASE_BLOCK_CORRUPTION视图报告损坏的块。该视图的字段FILE#表示AFN,字段BLOCK#表示BL。
b. 定位损坏的对象
一旦AFN被识别,执行以下SQL语句定位损坏的对象:
SQL> select *
From DBA_EXTENTS
Where file_id=&AFN
And &BL BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS-1;
如果损坏的块是数据文件开头,这将导致数据库无法正常启动和关闭,并且使用RMAN BLOCKRECOVER也不能恢复。因此此时就要进行完全恢复或者尝试使用BBED修改块头。
1) 模拟损坏数据文件头的块
使用BBED方法将数据文件6的第1个块损坏,DBV的检查结果如下:
$ dbv file=/test/test01.dbf
2) 尝试使用RMAN BLOCKRECOVER进行恢复
执行以下命令使用RMAN的BLOCKRECOVER对数据文件6的第1个块进行恢复:
RMAN> blockrecover datafile 6 block 1;
Starting recover as 2013-12-07 16:24
Using channel ORA_DISK_1
Starting media recovery
Media recovery complete,elapsed time: 00:00:00
Finished recover at 2013-12-07 16:24
恢复显示是完成的,也没有报错。但是执行DBV验证命令发现标记的坏块还是两个,及没有真正修复。说明使用RMAN BLOCKRECOVER对数据文件头的修复是没有作用的。
尝试正常关闭数据库,由于数据库无法完成检查点工作,所以正常关闭操作失败:
SQL> shutdown immediate
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: ‘/test/test01.dbf’
ORA-01210: data file header is media corrupt
强制关闭数据库:
SQL> shutdown abort
重启数据库,发现数据库无法打开数据文件:
SQL> startup
……
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: ‘/test/test01.dbf’
ORA-01210: data file header is media corrupt
3) 执行数据文件的完全恢复
执行以下命令还原、恢复6号数据文件:
RMAN> restore datafile 6;
RMAN> recover datafile 6;
尝试打开数据库:
SQL> alter database open;
Database altered.
Oracle数据库中有各种各样的块,如空块、表头块、数据块、索引块、数据文件头块、UNDO段块等。如果损坏的是普通表的数据块,那即不会影响启动数据库,也不会影响其他表的正常访问,只是在访问该表的时候会出现问题。如果损坏的是数据文件的块头,那么将导致数据库无法正常启动和停止,执行块恢复不能修复这个问题,执行数据文件的完全恢复才能恢复数据文件块头的损坏或尝试使用BBED修改数据文件块头。
不完全恢复又称为数据库基于时间点恢复,是将整个数据库恢复到之前的某个时间点、日志序列号或者SCN号。如下不完全恢复的选项:
不完全恢复的选项
不完全恢复方式 |
RMAN选项 |
用户管理备份选项 |
恢复到某个时间点 |
until time |
until time |
恢复到某个日志序列号 |
until suquence |
until cancel |
恢复到某个SCN号 |
until SCN |
until change |
不完全恢复只能针对整个数据库而言,并不能执行数据文件和表空间的不完全恢复;另外,对于非归档模式的恢复来说,也不能执行不完全恢复。
1) 基于时间点的不完全恢复
RMAN> run {
shutdown immediate;
startup mount;
SQL “alter session set nls_date_format=’’YYYY-MM-DD HH24:MI:SS’’”;(两个单引号之间没有空格)
set until time ‘2013-12-07 17:24:00’;
restore database;
recover database;
alter database open resetlogs;}
SET UNTIL TIME时间可以使用多种表示方式,可以使用TO_DATE函数来表示时间,还可以使用SYSDATE-1方式来表示时间。
注意:不完全恢复是针对整个数据而言,如果在上面的脚本中,还原和恢复的是某个数据文件或表空间,那么脚本将忽略set until time设置,对数据文件或表空间进行完全恢复。对RESTORE命令指定until time或者until scn的意义在于这样可以自动选择最近的RMAN备份来恢复数据,以上的批量命令相当于为RESTORE和RECOVER都指定了until time子句,这样比单命令模式更加简单和合理。基于时间点的恢复不能恢复到最终备份完成时间点以前的时段。
2) 基于序列号的不完全恢复
基于序列号的不完全恢复须指定某个Redo线程的序列号,那么在这个序列号切换时间点之前的所有实例的归档日志都需要的,每个节点的负载不同,其他实例的序列号可能比指定的Redo线程序列号要大。
以下是在RMAN中基于日志序列号的不完全恢复的例子:
RMAN> run {
Shutdown immediate;
Startup mount;
Set until sequence 10350 thread 1;
Restore database;
Recover database;
Alter database open resetlogs;}
注意:指定线程序列号为10350,但是恢复是不包含该序列号的日志的,也就是说恢复只会恢复到thread 1 sequence 10304的日志,时间点和scn恢复同样如此。
3) 基于SCN的不完全恢复
下面是在RMAN中基于SCN的不完全恢复的例子:
RMAN> run {
shutdown immediate;
startup mount;
set until scn 324394;
restore database;
recover database;
alter database open resetlogs;}
注意:对打开的数据库执行的全库备份或者0级备份,即使不完全恢复到执行全库备份或者0级备份的备份时间点也可能需要部分Redo日志,原因在于对打开的数据库执行RMAN备份是一个不一致的备份。
表空间时间点恢复(Tablespace Point-in-time Recovery,TSPITR)特性可以恢复一个或更多的表空间早于数据库其他部分的某个时间点。表空间时间点恢复是表空间的不完全恢复,操作起来比较复杂。
表空间时间点恢复能在不影响数据库其它表空间和对象的情况下,恢复一个或更多的用户表空间到之前的某个时间点。表空间时间点恢复是对某个表空间执行基于某个时间点的恢复,是特殊的不完全恢复。RMAN TSPITR可以用于以下场景:
n 一个不正确的job或者DML语句破坏了数据库其中一个表空间的数据,RMAN TSPITR可用于被破坏表空间的恢复。
n DDL操作改变了表的结构之后,RMAN TSPITR可用于丢失数据的恢复。这种情况不能使用Flashback Table找回表之前的结构的数据,如表结构变化后的一个TRUNCATE表操作。
n 一个表被一个drop语句加了purge选项彻底drop。RMAN TSPITR可用于这种情况的恢复。
n 恢复drop的表空间,当没有使用恢复目录,RMAN能对被drop的表空间执行TSPITR。
n 从一个表的逻辑损坏中恢复。
表空间时间点恢复和Flashback有点类似,在没有介质失败的情况下,数据也可以使用Flashback Database找回,但是Flashback Database会导致整个数据库被闪回到之前的某个时间点。与TSPITR不同的是,Flashback Database特性必须产生Flashback日志,使用Flashback Database闪回数据库比使用TSPITR有更多的限制,TSPITR可以扩展到能找回可用于恢复的更早备份数据。
1) TSPITR的工作原理
TSPITR工作原理的5个步骤:
步骤1 在辅助实例上用目标数据库的备份集还原数据文件。
步骤2 在辅助实例上用目标数据库的归档文件恢复数据文件。
步骤3 在辅助数据库上导出相关数据。
步骤4 修改主库的控制文件。
步骤5 将辅助数据上导出的文件导入目标数据库。
2) RMAN TSPITR模式
表空间时间点恢复使用的是RMAN的RECOVER tablespace命令,执行RMAN TSPITR有几个选项,不同的选项协调各种不同的操作模式之间对特定环境的自动化操作。
a. 全自动化(默认方式)
在这种模式下,RMAN管理整个TSPITR过程。制定表空间的恢复集、辅助目的地、目标时间和允许RMAN管理所有TSPITR的其它方面。
b. 自动化
可以覆盖一些默认RMAN TSPITR设置,但仍然使用RMAN管理辅助实例和辅助目的地。这是默认方式的变种,RMAN TSPITR提供一些固定管理的同事允许手动指定一些参数,主要包含以下两个参数:
n 辅助集或恢复集文件的位置
n 初始化参数文件
除了在TSPITR之后的恢复集文件位置,在TSPITR期间的辅助集文件、通道设置和参数或辅助实例的其它方面等更多控制都推荐使用默认方式。全自动和自动化都是使用RMAN自动管理辅助实例。
c. 非自动化
使用这种模式是手动创建和管理辅助实例的所有方面和一部分TSPITR过程。当必须分配不同的通道或者使用用户管理辅助实例改变参数时,使用这种模式是合适的。
3) 执行全自动化的TSPITR
下面以默认的全自动化模式在目标数据库服务器创建辅助数据库构建TSPITR,恢复在目标数据库对表的一个误操作。目标数据库与辅助数据库都在一台服务器上,下表是两个数据库的实例名和数据库名称对照表:
数据库类型 |
实例名称 |
数据库名称 |
目标数据库 |
test |
test |
辅助数据库 |
test2 |
test |
a. 创建模拟环境
步骤1 在目标数据创建测试表空间xy_tbs:
SQL> create tablespace xy_tbs datafile ‘/u01/app/oracle/test/xy_tbs01.dbf’ size 5M;
步骤2 确保目标数据库处在归档模式,使用RMAN查找出xy_tbs表空间的file_id,对它进行备份:
RMAN> report schema;
……
RMAN> backup datafile 5;
步骤3 创建测试用户xiaoyang:
SQL> create user xiaoyang identified by xiaoyang default tablespace xy_tbs tempory tablespace temp;
SQL> grant create session,create table,unlimited tablespace to xiaoyang;
SQL> connect xiaoyang/xiaoyang;
步骤4 创建两个测试表:x1和x2,每个表插入一条测试数据:
SQL> create table x1(D date);
SQL> create table x2(D2 date);
SQL> insert into x1 values(sysdate);
SQL> insert into x2 values(sysdate);
SQL> commit;
步骤5 查看当前时间作为表空间的恢复时间点:
SQL> alter session set nls_date_format=’YYYY-MM-DD HH24:MI:SS’;
SQL> select sysdate from dual;
步骤6 在恢复时间点之后向x2表中插入一条数据和创建一个新表x3,向x3插入一条测试数据:
SQL> insert into x2 values(sysdate);
SQL> create table x3(D3 date);
SQL> insert into x3 values(sysdate);
SQL> commit;
步骤7 手动drop掉表x1:
SQL> drop table x1 purge;
假设drop x1表是一个误操作,现在要通过TSPITR恢复技术恢复该表。
b. 检查表空间是否自关联
执行以下SQL语句检查表空间自关联情况:
SQL> execute dbms_tts.transport_set_check(‘xy_tbs’,true,true);
SQL> select * from transport_set_violations;
如果查询transport_set_violations视图有值返回,说明表空间有自关联,需要手动处理提示的问题。
c. 标识TSPITR之后将会丢失的对象
步骤1 通过时间标识TSPITR之后将会丢失的对象:
SQL> select owner,name,tablespace_name,to_char(creation_time,’YYYY-MM-DD HH24:MI:SS’) from ts_pitr_objects_to_be_dropped where tablespace_name in(‘xy_tbs’) and creation_time > to_date(‘2013-12-08 09:43:00’,’YYYY-MM-DD HH24:MI:SS’) order by tablespace_name,creation_time;
步骤2 通过SCN标识TSPITR之后将会丢失的对象:
SQL> select owner,names,tablespace_name,to_char(creation_time,’YYYY-MM-DD HH24:MI:SS’) from ts_pitr_objects_to_be_dropped where tablespace_name in(‘xy_tbs’) and creation_time > to_date(to_char(scn_to_timestamp(1638492),’YYYY-MM-DD HH24:MI:SS’),’YYYY-MM-DD HH24:MI:SS’) order by tablespace_name,creation_time;
如果以上两个查询有结果返回,那么在执行TSPITR之前应该先将这些对象进行逻辑备份,TSPITR完成之后,再将这些对象以替换的方式导入,以恢复产生数据丢失的对象。
d. 创建辅助数据库参数文件
转储目标数据库参数文件,将该参数文件拷贝到$ORACLE_HOME目录,重命名为inittest2.ora,参考如下参数文件内容调整inittest2.ora实例的初始化参数文件:
*.audit_file_dest=’/u01/app/oracle/admin/test2/adump’
*.control_files=’/u01/app/oracle/oradata/test2/control01.ctl’
……
db_file_name_convert=(“/u01/app/oracle/oradata/test”,”/u01/app/oracle/oradata/test2”)
log_file_name_convert=(“/u01/app/oracle/oradata/test”,”/u01/app/oracle/oradata/test2”)
log_archive_start=false
lock_name_space=test2
修改test2实例初始化参数文件中的audit_file_dest、control_file参数,确保与原有数据库的存储位置不同。添加db_file_name_convert、log_file_name_convert、log_archive_start和lock_name_space参数设置。
e. 创建目录结构
根据实例test2参数的设置创建相应的目录结构:
$ mkdir –p /u01/app/oracle/admin/test2/adump
$ mkdir –p /u01/app/oracle/oradata/test2
f. 创建test2实例密码文件
$ cd $ORACLE_HOME/dbs/
$ orapwd file=orapwtest2 password=oracle entries=5
g. 创建辅助数据库实例的静态注册
在grid用户下的$GRID_HOME/network/admin/listener.ora文件中修改如下配置:
$ cat listener.ora
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = test2)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1)
(SID_NAME = test2)
)
)
h. 添加Oracle Net本地服务名
在Oracle用户下的$ORACLE_HOME/network/admin/tnsnames.ora文件中添加如下配置:
TEST2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rhel2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test2)
)
)
i. 启动辅助数据库到NOMOUNT状态
$ export ORACLE_SID=test2
$ sqlplus / as sysdba
SQL> create spfile from pfile;
SQL> startup nomount
j. 执行TSPITR恢复
使用RMAN同时连接到目标数据库和辅助数据库,使用RECOVER TABLESPACE命令执行TSPITR操作:
$ rman target /
RMAN> connect auxiliary sys/oracle@test2
RMAN> run {
allocate auxiliary channel a1 type disk;
allocate channel c1 type disk;
recover tablespace xy_tbs until time “to_date(‘2013-12-08 09:30:00’,’YYYY-MM-DD HH24:MI:SS’)”;
release channel c1;
}
执行TSPITR需要手动分配auxiliary通道
使目标数据中xy_tbs表空间ONLINE:
SQL> alter tablespace xy_tbs online;
k. 验证恢复结果
SQL> select * from xiaoyang.x1;
SQL> select * from xiaoyang.x2;
SQL> select * from xiaoyang.x3;
对于正常关闭的数据库来说,关闭前会执行一个检查点以保证数据库的一致性,重启之后,联机日志是是否存在都不会导致数据的丢失。然而,如果是非正常关闭的数据库,重启之后会执行实例恢复的过程,如果实例恢复过程需要的UNDO活Redo日志丢失,那么就可能造成数据的不一致和数据的丢失。
a. 连接Redo日志损坏的4种情况
联机Redo日志文件的损坏有以下4中情况:
情况1 非当前日志损坏,正常关闭数据库。
情况2 非当前日志损坏,非正常关闭数据库。
情况3 当前日志损坏,正常关闭数据库。
情况4 当前日志损坏,非正常关闭数据库。
b. 处理方法
1) 情况1和情况2的处理方法
情况1和情况2的处理方法一样,直接把日志文件清除即可:
SQL> alter database clear logfile group 3;
2) 情况3的处理方法
在SQLPLUS中执行以下的SQL语句以RESETLOGS模式重新打开数据库:
SQL> startup mount;
SQL> recover database until cancel;
SQL> alter database open resetlogs;
3) 情况4的处理方法
这种情况会导致联机Redo日志中的一部分已提交的数据丢失,实例恢复中的前滚操作不能成功执行,回滚操作也无法执行,这也会导致部分数据的丢失。处理方法是强制打开数据库或通过备份执行介质不完全恢复。
数据库的脱机包括数据文件的脱机和表空间的脱机,数据文件的脱机和表空间非正常脱机在下一次执行联机命令之前都无需先执行介质恢复操作,介质恢复成功才能联机成功。
数据文件添加到表空间之后不能再被删除,也没有语法支持这么做,如果不想使用该数据文件,唯一的方法是将数据文件设置为OFFLINE状态。执行以下步骤将数据文件设置为OFFLINE状态:
1) 如果是归档模式可以执行如下SQL语句设置数据文件的状态为OFFLINE:
SQL> alter database datafile ‘xxx.dbf’ offline;
2) 如果是非归档模式执行以下SQL语句将数据文件状态设置为OFFLINE:
SQL> alter database datafile ‘xxx.dbf’ offile drop;
即使数据文件脱机,数据文件相关的数据字典信息、元数据信息依然存在,当表空间被删除后,相关数据文件的信息才会被清除。Drop tablespace只是清空Oracle数据字典信息,即使数据文件不存在也可以正常的drop表空间。对于数据文件的脱机,在设置该数据文件OFFLINE的时候都需要对该数据文件执行介质恢复。
如果在非归档模式下使用OFFLINE drop使数据文件脱机,这就意味着该数据文件可能无法再恢复到online状态,原因在于非归档模式下可能没有足够的日志文件在执行online的时候完成介质恢复。如果数据文件脱机之后日志没有发生切换,所有需要的日志还依然存在的话,那么非归档模式下数据文件的脱机也可以再次变成online状态。
表空间脱机实际就是表空间对应的所有数据文件脱机。
表空间脱机分为正常脱机、临时脱机和立即脱机,如下:
1) 正常脱机
这是默认的选项,如果表空间正常脱机,当重新执行online的时候,Oracle会用相应的SCN来更新表空间数据文件头SCN即可正常地online表空间,而不需要执行介质恢复。执行以下SQL语句是表空间正常脱机:
SQL> alter tablespace xxx offline;
2) 临时脱机
当执行临时脱机(OFFLINE temporary)语句之前已经有表空间对应的数据文件脱机,那么在是表空间重新online之前需要执行特定数据文件的介质恢复。执行以下的SQL语句是表空间临时脱机:
SQL> alter tablespace xxx offline temporary;
3) 立即脱机
执行这个操作(OFFLINE immediate)表示立即使表空间脱机,在下次使表空间online的时候必须执行介质恢复,介质恢复成功之后表空间才能变成online状态。执行以下的SQL语句是表空间立即脱机:
SQL> alter tablespace xxx offline immediate;
...............................................................................................................................
● 本文来自于itpub转载文章,若有侵权,请联系小麦苗及时删除,非常感谢原创作者fengpinDBA的无私奉献
● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● QQ群:230161599 微信群:私聊
● 原文地址:http://blog.itpub.net/29339097/viewspace-1062090/
● 小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● QQ群: 230161599 微信群:私聊
● 联系我请加QQ好友(642808185),注明添加缘由
●【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】
...............................................................................................................................
手机长按下图识别二维码或微信客户端扫描下边的二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,免费学习最实用的数据库技术。