您的位置:首页 > 数据库 > Oracle

oracle 的redo和undo

2016-02-29 21:43 239 查看
来自http://www.inthirties.com/thread-239-1-1.html

在这里会介绍UNDO,REDO是如何产生的,对TRANSACTIONS的影响,以及他们之间如何协同工作的。

什么是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了。

COMMIT 以前,常想当然地认为,一个大的TRANSACTION(比如大批量地INSERT数据)的COMMIT会花费时间比短的TRANSACTION长。而事实上是没有什么区别的,

因为ORACLE在COMMIT之前已经把该写的东西写到DISK中了,

我们COMMIT只是

1,产生一个SCN给我们TRANSACTION,SCN简单理解就是给TRANSACTION排队,以便恢复和保持一致性。

2,REDO写REDO到DISK中(LGWR,这就是log file sync),记录SCN在ONLINE REDO LOG,当这一步发生时,我们可以说事实上已经提交了,这个TRANSACTION已经结束(在V$TRANSACTION里消失了)

3,SESSION所拥有的LOCK(V$LOCK)被释放。

4,Block Cleanout(这个问题是产生ORA-01555: snapshot too old的根本原因) ROLLBACK ROLLBACK和COMMIT正好相反,ROLLBACK的时间和TRANSACTION的大小有直接关系。因为ROLLBACK必须物理上恢复数据。COMMIT之所以快,是因为ORACLE在COMMIT之前已经作了很多工作(产生UNDO,修改BLOCK,REDO,LATCH分配),

ROLLBACK慢也是基于相同的原因。

ROLLBACK会

1,恢复数据,DELETE的就重新INSERT,INSERT的就重新DELETE,UPDATE的就再UPDATE。

2,RELEASE LOCK ROLLBACK要比COMMIT消耗更多资源,因为ORACLE认为你一旦做数据更新,那么就意味着你要COMMIT(其他数据库不全是这种设计理念,比如DB2),所以在你更新数据的时候就做了大量的工作,这也可以理解为什么不建议用TABLE来做TEMPORARY TABLE。(TEMP TABLE消耗的REDO比固定表在INSERT时要少很多 ,UPDATE时差不多是1/2,

但是DELETE却相差无几) REDO 产生REDO 越多,你的系统越慢,不但影响你自己的SESSION,还影响其他SESSION,LGWR管理REDO,并且是TRANSACTION的结束标志。

首先要知道怎么监控REDO,当然,SET AUTOTRACE ON可以,不过只能监控DML语句,而像PROCEDURE则无法监视。那么我们就需要观察字典了,V$MYSTAT, V$STATNAME,

前面有两个脚本,mystat,mystat2

SQL> @mystat "redo size"

NAME VALUE

redo size 1016784

SQL> insert into t select * from big_table; 已创建46990行。

SQL> @mystat2

NAME VALUE DIFF

redo size 6604308 5,587,524

看到产生了5,587,524的REDO,再对比下用NOLOG插入

SQL> @mystat "redo size"

NAME VALUE

redo size 6604308

SQL> insert /*+ APPEND */ into t select * from big_table;

已创建46990行。

SQL> @mystat2

NAME VALUE DIFF

redo size 6616220 11,912

看到APPEND插入用了11,912字节的REDO,比一般性插入要少很多。或者用这个PROCEDURE也可以观察SQL消耗的REDO

引用:
SQL>create or replace procedure do_sql( p_sql in varchar2 )

2 as

3 l_start_redo number;

4 l_redo number;

5 begin

6 select v$mystat.value

7 into l_start_redo

8 from v$mystat, v$statname

9 where v$mystat.statistic# = v$statname.statistic#

10 and v$statname.name = 'redo size';

11

12 execute immediate p_sql;

13 commit;

14

15 select v$mystat.value-l_start_redo

16 into l_redo

17 from v$mystat, v$statname

18 where v$mystat.statistic# = v$statname.statistic#

19 and v$statname.name = 'redo size';

20

21 dbms_output.put_line

22 ( to_char(l_redo,'9,999,999') ||' bytes of redo generated for "' ||

23 substr( replace( p_sql, chr(10), ' '), 1, 25 ) || '"...' );

24 end;

25 /

用法就不多说了。 减少REDO 既然REDO这么消耗资源,那我们能屏蔽REDO吗?显然不能,那我们能减少REDO吗?这是可以的(注意,9.2以后,可以用FORCE LOGGING开关来控制是否强制REDO,如果YES,则不管NOLOGGING还是APPEND都是不起任何作用的,可以SELECT FORCE_LOGGING FROM V$DATABASE查看是否FORCE。另外需要明白,没有一个办法能彻底不记录REDO,只能是减少REDO。因为不管如何,数据字典总是要产生一些REDO的。 create table
nologging as select xxx新建的表没有原来表的索引和默认值,只有非空(not null)的约束素条件可以继承过来. INSERT /*+ APPEND */ INTO target_tablename SELECT 如果运行此命令时还有对target_tablename的DML操作会排队在它后面,对OLTP系统在用的表操作是不合适的。快速插入数据可以指定append提示,但是需要注意 noarchivelog模式下,默认用了append就是nologging模式的。 在archivelog下,需要把表设置程Nologging模式。可以通过如下语句设置为NO
FORCE LOGGING。 Alter database no force logging; 这两种方法转移数据时没有用SGA里数据缓冲区和事物处理的回滚段, 也不写联机事物日志,就象数据库装载工具SQLLOAD一样直接把数据写到物理文件。 REDO的问题

有时,会在ALERT中发现

Thread 1 cannot allocate new log, sequence 1466 Checkpoint not complete Current log# 3 seq# 1465 mem# 0: /home/ora10g/oradata/ora10g/redo03.log

这问题出现在系统尝试reuse online redo log file但是却没有可用的。可能是由于DBWR没有完成(Checkpoint not complete)或ARCH没有完成。

1,DBWR,用多DBWR process,合理分布数据,

2,增加REDO LOG FILE

3,扩大REDO的大小

4,让CHECKPOINT发生更频繁,可以减少block buffer cache,FAST_START_MTTR_TARGET, LOG_CHECKPOINT_INTERVAL,LOG_CHECKPOINT_TIMEOUT。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: