redo > undo >datafile insert一条记录时 表跟undo的信息都会放进 redo 中 在mit 或之前 redo 的信息会放进硬盘上 故障时 redo 便可恢复那些已经mit 了的数据 redo >每次 *** 作都先记录到redo日志中 当出现实例故障(像断电) 导致数据未能更新到数据文件 则数据库重启时须redo 重新把数据更新到数据文件 undo >记录更改前的一份copy 但你系统rollback时 把这份copy重新覆盖到原来的数据 redo >记录所有 *** 作 用于恢复(redo records all the database transaction used for recovery) undo >记录所有的前印象 用于回滚(undo is used to store unmited data infor used for rollback) redo >已递交的事务 实例恢复时要写到数据文件去的 undo >未递交的事务 redo的原因是 每次mit时 将数据的修改立即写到online redo中 但是并不一定同时将该数据的修改写到数据文件中 因为该数据已经提交 但是只存在联机日志文件中 所以在恢复时需要将数据从联机日志文件中找出来 重新应用一下 使已经更改数据在数据文件中也改过来!
undo的原因是 在oracle正常运行时 为了提高效率 加入用户还没有mit 但是空闲内存不多时 会由DBWR进程将脏块写入到数据文件中 以便腾出宝贵的内存供其它进程使用 这就是需要UNDO的原因 因为还没有发出mit语句 但是oracle的dbwr进程已经将没有提交的数据写到数据文件中去了 undo 也是也是datafile 可能dirty buffer 没有写回到磁盘里面去 只有先redo apply 成功了 才能保证undo datafile 里面的东西都是正确的 然后才能rollback 做undo的目的是使系统恢复到系统崩溃前(关机前)的状态 再进行redo是保证系统的一致性 不做undo 系统就不会知道之前的状态 redo就无从谈起 所以instance crash recovery 的时候总是先rollforward 再rollback undo 回退段中的数据是以 回退条目 方式存储 回退条目=块信息(在事务中发生改动的块的编号)+在事务提交前存储在块中的数据 在每一个回退段中oracle都为其维护一张 事务表 在事务表中记录著与该回退段中所有回退条目相关的事务编号(事务SCN&回退条目) redo 重做记录由一组 变更向量 组成 每个变更变量中记录了事务对数据库中某个块所做的修改
当用户提交一条mit语句时 LGWR进程会立刻将一条提交记录写入到重做日志文件中 然后再开始写入与该事务相关的重做信息 #事务提交成功后 Oracle将为该事备生成一个系统变更码(SCN) 事务的SCN将同时记录在它的提交记录和重做记录中
mit 提交事务前完成的工作
·在SGA区的回退缓存中生成该事务的回退条目 在回退条目中保存有该事务所修改的数据的原始版本
·在SGA区的重做日志缓存中生成该事务的重做记录 重做记录中记载了该事务对数据块所进行的修改 并且还记载了对回退段中的数据块所进行的修改 缓存中的重做记录有可能在事务提交之前就写入硬盘中
·在SGA区的数据库缓丰中记录了事务对数据库所进行的修改 这些修改也有可能在事务提交之前就写入硬盘中
提交事务时完成的工作
·在为该事务指定的回退段中的内部事务表内记录下这个事务已经被提交 并且生成一个惟一的SCN记录在内部事务表中 用于惟一标识这个事务
·LGWR后进进程将SGA区重做日志缓存中的重做记录写入联机重做日志文件 在写入重做日志的同时还将写入该事务的SCN
·Oracle服务进程释放事务所使用的所有记录锁与表锁
·Oracle通知用户事务提交完成
·Oracle将该事务标记为已完成
rollback 回退事务完成的工作
·Oracle通过使用回退段中的回退条目 撤销事务中所有SQL语句对数据库所做的修改
·Oracle服务进程释放事务所使用的所有锁
·Oracle通知事务回退成功
·Oracle将该事务标记为已完成
lishixinzhi/Article/program/Oracle/201311/16931
首先,undo表空间满是正常的,oracle自然会重用或者扩展它,一般不用管它。
然后,现在要解决的话,需要先把undo
tablespace设置成手动,启动数据库,创建新的undo
tablespace。把新的设置成默认的。
假设你的库现在是mounted状态
1
创建PFILE(如果已有就是更新)
SQL>create
pfile
from
spfile;
2
关闭数据库
SQL>shutdown
immediate
3
在你的$ORACLE_HOME/dbs目录下面找个叫做
init<数据库>ora的文件,把其中有undo_management=AUTO的一行改成
undo_management=MANUAL
如果没有就在文件末尾填一行
4
以sysdba身份连接数据库
SQL>connect
"/
as
sysdba"
用刚才改过的文件启动数据库
SQL>
startup
pfile=<刚才的文件全路径和名字>
这步是最关键的,如果成功,后面就没问题了
5
drop掉原来的表空间
SQL>
drop
tablespace
<原来的undo表空间名字>
including
contents;
6
创建新的undo表空间
SQL>
create
UNDO
tablespace
undotbs2
datafile
'/u01/app/oracle/oradata/orcl/undotbs02dbf'
size
100M
autoextend
on;
7
关闭数据库,
SQL>shutdown
immediate
在开始那个init文件里设置UNDO_MANAGEMENT=AUTO
和
UNDO_TABLESPACE=UNDOTBS2
8
再做一次第四步
9
更新spfile
SQL>create
spfile
from
pfile;
10
关闭数据库,正常重新启动
SQL>shutdown
immediate
SQL>startup
11
去网上教你删undo那个地方骂它。非常想当然的做法。没有任何理由这么做
12
让你的工程师去学oracle
培训
以上步骤的中的第5步可能会出问题。我不确认。。。
但是即使第5步不成功,问题应该也不大
最近遇到个比较有意思的问题,服务器宕掉后无法启动,想了好多办法,虽然解决了问题,数据没有丢失,但是没有按照自已的思路来,未免还是有些不甘。遇到问题不能慌,尤其是线上的环境,更不能紧张,心理素质对DBA来说也是一项挑战,可能你的手一抖就会导致多少人无法正常使用业务,如果你没有把握,请先把现场环境备份后再进行 *** 作,避免数据的二次损坏,下面壹基比小喻说一下大概的思路吧。
1检查是否有备份,如果备份存在,binlog存在,那么万事大吉,一切都有挽回的余地,慢慢来搞,只要你基础扎实,数据还原只是时间的问题。
2对于没有备份的,那处理这个问题就有些棘手了,还得一步一步的来。
在mycnf中[mysqld]下加上以下配置,采用强制恢复机制,看是否能够启动
[mysqld]
innodb_force_recovery=1
如果设置成1不能启动,可以逐渐的将数据增大到6,下文会详细说下1-6是什么意思,如果在1-6之间启动成功了,那么你运气还不错,这时候不要恢复业务,赶紧把数据用逻辑方式导出来,再启个新的实例把数据还原,有人会问,为什么mysql已经启动了,还要导出数据呢,原因在这:
当innodb_force_recovery被设置为大于0的时候 ,会阻止用户insert,update,delete也就是你启动的mysql不是一个正常的mysql服务,类似于windows系统下的安全模式。以下这段引于其它地方,具体地址不太清楚了,也可以从官方文档中找到。
innodb_force_recovery被允许的非零值如下。一个更大的数字包含所有更小数字的预防措施。如果你能够用一个多数是4的选项值来转储你的表,那么你是比较安全的,只有一些在损坏的单独页面上的数据会丢失。一个为6的值更夸张,因为数据库页被留在一个陈旧的状态,这个状态反过来可以引发对B树和其它数据库结构的更多破坏。
innodb_force_recovery=1 (SRV_FORCE_IGNORE_CORRUPT)
即使服务器检测到一个损坏的页,也让服务器运行着;试着让SELECT FROM tbl_name 跳过损坏的索引记录和页,这样有助于转储表。
innodb_force_recovery=2 (SRV_FORCE_NO_BACKGROUND)
阻止主线程运行,如果崩溃可能在净化 *** 作过程中发生,这将阻止它。
innodb_force_recovery=3 (SRV_FORCE_NO_TRX_UNDO)
恢复后不运行事务回滚。
innodb_force_recovery=4 (SRV_FORCE_NO_IBUF_MERGE)
也阻止插入缓冲合并 *** 作。如果你可能会导致一个崩溃。最好不要做这些 *** 作,不要计算表统计表。
innodb_force_recovery=5 (SRV_FORCE_NO_UNDO_LOG_SCAN)
启动数据库之时不查看未完成日志:InnoDB把未完成的事务视为已提交的。
innodb_force_recovery=6 (SRV_FORCE_NO_LOG_REDO)
不要在恢复连接中做日志前滚。
数据库不能另外地带着这些选项中被允许的选项来使用。作为一个安全措施,当innodb_force_recovery被设置为大于0的值时,InnoDB阻止用户执行INSERT, UPDATE或DELETE *** 作
即使强制恢复被使用,你也可以DROP或CREATE表。如果你知道一个给定的表正在导致回滚崩溃,你可以移除它。你也可以用这个来停止由失败的大宗导入或失败的ALTER TABLE导致的失控回滚。你可以杀掉mysqld进程,然后设置innodb_force_recovery为3,使得数据库被挂起而不需要回滚,然后舍弃导致失控回滚的表。
关于上面进行逻辑备份也可能会遇到问题,可能会备份失败,如果出错,建议先按库一个一个的备份,到哪个库出错后,再按照当前库的表一个一个备份,表出错根据表中主键一点一点备份,最终将大部分数据导出。如果你的数据不重要,可以容忍丢失,那么可以当我说的都是废话了。
3如果还是不可以启动,那么恭喜你,你遇到挑战了。
查看错误日志,看没有提示因为某个表的原因而导致启动不了,可以先把损坏的表的ibd文件先从数据目录mv走,再试着启动,在数据已经恢复后,我把当时错误的文件拿到本地,做了测试,把几个报错的ibd文件mv走后,数据库就可以正常启动了,但是mv走的这几个表数据会丢失。怎么把这个表的数据弄回来呢,曾想过用在线表空间传输,但是cfg文件却没有,这种方法没有行通。后来用Percona Data Recovery Tool for InnoDB工具进行数据恢复,关于这个工具的介绍与 *** 作,网上一大堆,我就不详细说明了。
用来保证数据读一致的。数据再修改前会放入undo空间,如果修改失败了回滚会用到undo中的信息。还有其他用户正在被修改的数据时是都的undo表空间的数据,保证数据一致。
redo是联机日志,没有单独的表空间
什么是REDO
REDO记录transaction logs 分为online和archived 以恢复为目的
比如 机器停电 那么在重起之后需要online redo logs去恢复系统到失败点
比如 磁盘坏了 需要用archived redo logs和online redo logs区恢复数据
比如 truncate一个表或其他的 *** 作 想恢复到之前的状态 同样也需要
什么是UNDO
REDO 是为了重新实现你的 *** 作 而UNDO相反 是为了撤销你做的 *** 作 比如你得一个TRANSACTION执行失败了或你自己后悔了 则需要用 ROLLBACK命令回退到 *** 作之前 回滚是在逻辑层面实现而不是物理层面 因为在一个多用户系统中 数据结构 blocks等都在时时变化 比如我们 INSERT一个数据 表的空间不够 扩展了一个新的EXTENT 我们的数据保存在这新的EXTENT里 其它用户随后也在这EXTENT里插入了数据 而此时我想ROLLBACK 那么显然物理上讲这EXTENT撤销是不可能的 因为这么做会影响其他用户的 *** 作 所以 ROLLBACK是逻辑上回滚 比如对INSERT来说 那么ROLLBACK就是DELETE了
MIT 以前 常想当然地认为 一个大的TRANSACTION(比如大批量地INSERT数据)的MIT会花费时间比短的TRANSACTION长 而事实上是没有什么区别的
因为ORACLE在MIT之前已经把该写的东西写到DISK中了
我们MIT只是
产生一个SCN给我们TRANSACTION SCN简单理解就是给TRANSACTION排队 以便恢复和保持一致性
REDO写REDO到DISK中(LGWR 这就是log file sync) 记录SCN在ONLINE REDO LOG 当这一步发生时 我们可以说事实上已经提交了 这个TRANSACTION已经结束(在V$TRANSACTION里消失了)
SESSION所拥有的LOCK(V$LOCK)被释放
Block Cleanout(这个问题是产生ORA : snapshot too old的根本原因) ROLLBACK ROLLBACK和MIT正好相反 ROLLBACK的时间和TRANSACTION的大小有直接关系 因为ROLLBACK必须物理上恢复数据 MIT之所以快 是因为ORACLE在MIT之前已经作了很多工作(产生UNDO 修改BLOCK REDO LATCH分配) ROLLBACK慢也是基于相同的原因
UNDO表空间用于存放UNDO数据 当执行DML *** 作时 Oracle <;会将这些 *** 作的旧数据写入UNDO段 管理UNDO数据不仅可以使用回滚段 还可以使用UNDO表空间
UNDO数据的作用 当用户执行DML *** 作修改数据时 UNDO数据被存放在UNDO段 而新数据则被存放到数据段中 如果事务 *** 作存在问题 就需要回退事务 以取消事物变化
例如 执行完UPDATE emp SET sal= WHERE empno= 后 发现应该修改雇员 的工资 而不是 此时应该执行ROLLBACK语句
读一致性
用户检索数据时 ORACLE总是使用户只能看到被提交过的数据 这是由Oracle自动提供的 当用户修改数据 但是没有提交时 另外一个用户使用select语句查找该值时 该值就是从undo表空间中取得的
事务恢复
事务恢复是例程恢复的一部分 它是由Oracle Server自动完成的 如果在数据库运行过程中出线历程失败 那么当启动Oracle Server时 后台进程SMON会自动执行例程恢复 执行例程恢复时 Oracle会重做所有未应用的记录 然后打开数据库 回退未提交事务
倒叙查询
倒叙查询用于取得某一特定时间点的数据库数据
UNDO_MANAGEMENT
使用初始化参数用于指定UNDO数据的管理方式 如果使用自动管理模式 必须设置该参数为AUTO 此时采用UNDO表空间管理UNDO数据 如果使用手工管理模式 必须设置该值为MANUAl 此时采用回滚段管理UNDO数据
UNDO_TABLESPACE
用于指定例程所要使用的UNDO表空间 使用自动UNDO管理模式时 通过配置该参数可以指定例程所要使用的UNDO表空间
使用RAC结构时 必须为每个例程配置一个独立的UNDO表空间
UNDO_RETENTION
该参数用于控制UNDO数据的最大保留时间 其默认值为 秒 该值时倒叙查询可以查看到的最早时间点
lishixinzhi/Article/program/Oracle/201311/17025
以上就是关于Oracle的redo和undo的区别全部的内容,包括:Oracle的redo和undo的区别、oracle undo表空间被删除,数据库无法启动,请问如何恢复、网站宕机 服务器宕机 数据库宕机 宕机怎么办等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)