博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Oracle Redo and Undo
阅读量:2347 次
发布时间:2019-05-10

本文共 4266 字,大约阅读时间需要 14 分钟。

 在这里会介绍UNDOREDO是如何产生的,对TRANSACTIONS的影响,以及他们之间如何协同工作的。
什么是REDO
      REDO记录transaction logs,分为onlinearchived。以为目的。
      比如,机器停电,那么在重起之后需要online redo logs去恢复系统到失败点。
      比如,磁盘坏了,需要用archived redo logsonline redo logs区恢复数据。
      比如,truncate一个表或其他的操作,想恢复到之前的状态,同样也需要。
什么是UNDO
      REDO是为了重新实现你的操作,而UNDO相反,是为了撤销你做的操作,比如你得一个TRANSACTION执行失败了或你自己后悔了,则需要用ROLLBACK命令回退到操作之前。回滚是在逻辑层面实现而不是物理层面,因为在一个多用户系统中,数据结构,blocks等都在时时变化,比如我们INSERT一个数据,表的空间不够,扩展了一个新的EXTENT,我们的数据保存在这新的EXTENT里,其它用户随后也在这EXTENT里插入了数据,而此时我想ROLLBACK,那么显然物理上讲这EXTENT撤销是不可能的,因为这么做会影响其他用户的操作。所以,ROLLBACK是逻辑上回滚,比如对INSERT来说,那么ROLLBACK就是DELETE了。
COMMIT
      以前,常想当然地认为,一个大的TRANSACTION(比如大批量地INSERT数据)的COMMIT会花费时间比短的TRANSACTION长。而事实上是没有什么区别的,因为ORACLECOMMIT之前已经把该写的东西写到DISK中了,我们COMMIT只是
1,产生一个SCN给我们TRANSACTIONSCN简单理解就是给TRANSACTION排队,以便恢复和保持一致性。
2,REDOREDODISK中(LGWR,这就是log file sync),记录SCNONLINE REDO LOG,当这一步发生时,我们可以说事实上已经提交了,这个TRANSACTION已经结束(在V$TRANSACTION里消失了)
3,SESSION所拥有的LOCKV$LOCK)被释放。
4,Block Cleanout(这个问题是产生ORA-01555: snapshot too old的根本原因)
ROLLBACK
      ROLLBACKCOMMIT正好相反,ROLLBACK的时间和TRANSACTION的大小有直接关系。因为ROLLBACK必须物理上恢复数据。COMMIT之所以快,是因为ORACLECOMMIT之前已经作了很多工作(产生UNDO,修改BLOCKREDOLATCH分配),ROLLBACK慢也是基于相同的原因。
      ROLLBACK
      1,恢复数据,DELETE的就重新INSERTINSERT的就重新DELETEUPDATE的就再UPDATE
      2RELEASE LOCK
 
      ROLLBACK要比COMMIT消耗更多资源,因为ORACLE认为你一旦做数据更新,那么就意味着你要COMMIT(其他不全是这种设计理念,比如DB2,所以在你更新数据的时候就做了大量的工作,这也可以理解为什么不建议用TABLE来做TEMPORARY TABLE。(TEMP TABLE消耗的REDO比固定表在INSERT时要少很多     UPDATE时差不多是1/2,但是DELETE却相差无几
REDO
      产生REDO越多,你的系统越慢,不但影响你自己的SESSION,还影响其他SESSIONLGWRREDO,并且是TRANSACTION的结束标志。
      首先要知道怎么监控REDO,当然,SET AUTOTRACE ON可以,不过只能监控DML语句,而像PROCEDURE则无法监视。那么我们就需要观察字典了,V$MYSTAT, V$STATNAME,前面有两个脚本,mystatmystat2
SQL> @mystat "redo size"
NAME                                                                 VALUE
---------------------------------------------------------------- ----------
redo size                                                          1016784
SQL> insert into t select * from big_table;
已创建46990行。
SQL> @mystat2
NAME                                                                     V
---------------------------------------------------------------- ----------
DIFF
----------------
redo size                                                          6604308
      5,587,524
      看到产生了5,587,524REDO,再对比下用NOLOG插入
SQL> @mystat "redo size"
NAME                                                                 VALUE
---------------------------------------------------------------- ----------
redo size                                                          6604308
SQL> insert /*+ APPEND */ into t select * from big_table;
已创建46990行。
SQL> @mystat2
NAME                                                                     V
---------------------------------------------------------------- ----------
DIFF
----------------
redo size                                                          6616220
         11,912
      看到APPEND插入用了11,912字节的REDO,比一般性插入要少很多。
      或者用这个PROCEDURE也可以观察消耗的REDO
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
。(要考虑全面哟)

转载地址:http://pmpvb.baihongyu.com/

你可能感兴趣的文章
(二)博客部署到云端
查看>>
SpringCloud详解
查看>>
Win10下安装卸载Oracle11g的教程及各种坑
查看>>
Zookeeper
查看>>
更新mysql5.7修改字符集
查看>>
Windows系统护眼色设置
查看>>
JUC多线程&lambda之美&ThreadLocal
查看>>
碎片清理
查看>>
程序员不能错过的技术网站
查看>>
冒泡排序(分析+代码调优)
查看>>
Vue
查看>>
乐优商城总结
查看>>
如何使用Git上传和更新项目至Github
查看>>
选择排序(分析+代码调优)
查看>>
Docker
查看>>
代码优化建议,44条代码优化细节
查看>>
快速排序(图解分析+代码调优)
查看>>
Java基础面试总结
查看>>
HashMap遍历几种方式比较(传统的Map迭代方式对比JDK8的迭代方式)
查看>>
Java面试& HashMap实现原理分析
查看>>