首页 > 数据库 >Oracle——redo+undo总结

Oracle——redo+undo总结

时间:2023-08-18 16:00:58浏览次数:30  
标签:undo 生成 Oracle 日志 redo 重做

Oracle——redo+undo总结

 

《Oracle------redo》

重做日志文件(redo log file)对数据库来说至关重要,他们是数据库的事务日志;

Oracle数据库维护着两类重做日志文件:在线重做日志文件(redo)和 归档重做日志文件(archive log),(归档重做日志文件实际上就是已填满的“旧”在线重做日志文件的副本)

这两类重做日志文件都是用于恢复的:

①:如果数据库所在主机掉电,导致实例失败,Oracle会使用在线重做日志将系统恢复到恰好在掉电之前的那个提交点;

②:如果磁盘驱动器出现故障(这是介质失败),Oracle会使用归档重做日志以及在线重做日志,以及之前的一个备份,将原在此驱动器上的数据恢复到某个时间点;

 

每个Oracle数据库都至少有两个在线重做日志,每个组中至少有一个成员(重做日志文件),在线重做日志组会以循环的方式使用;

 

Redo log的日志状态分为4种:

current:指的是当前日志文件,该日志文件是活动的,当前正在被使用的,进行崩溃恢复时,Current日志文件是必须的;

ACTIVE:是活动的非当前日志,可以已经完成归档也可能没有归档,在Crash恢复时会被用到;

inactive:非活动日志,在实例恢复时不再需要,但是在介质恢复时可能会用到,此状态的日志也可能没有被归档。

unused:该日志从未被写入,这类日志可能是刚被添加到数据库或者在resetlogs之后被重置。 

 

《Oracle----undo》

REDO是为了重新实现你的操作,而UNDO相反,是为了撤销你做的操作,比如你得一个TRANSACTION执行失败了或你自己后悔了,则需要用ROLLBACK命令回退到操作之前。回滚是在逻辑层面实现而不是物理层面,因为在一个多用户系统中,数据结构,blocks等都在时时变化,比如我们INSERT一个数据,表的空间不够,扩展了一个新的EXTENT,我们的数据保存在这新的EXTENT里,其它用户随后也在这EXTENT里插入了数据,而此时我想ROLLBACK,那么显然物理上讲这EXTENT撤销是不可能的,因为这么做会影响其他用户的操作。所以,ROLLBACK是逻辑上回滚,比如对INSERT来说,那么ROLLBACK就是DELETE了。 

 

注意:redo是用于在失败时恢复事务,undo则用来取消一条语句或一组语句的作用。与redo不同,undo是存储在数据库内部一组特殊的段中,称为undo段

 

1、insert:

第一条insert into t 语句会同时生成redo和undo,它锁生成的undo信息足以使insert小时,而redo信息则足以让这个insert再次发生;我们可以看到,块缓冲区里面存放着修改完的undo块、索引块、和表数据块,所有的这些块都被重做日志缓冲区中相应条目所保护;

 

2、update

update 生成的undo量更大,比insert要大,这是因为由于update需要保存数据修改前的映像;update语句还放在重做日志缓冲区中;

 

3、delete:

delete会生成undo,块被修改,并把redo发送到重做日志缓冲区;

 

4、commit

当事务提交时,Oracle会把重做日志缓冲区刷新输出到磁盘;

 

注意:

insert生成的undo最少;(因为Oracle只是记录了一个rowid)

delete生成的undo最多;(因为Oracle必须把整行的删除前映像记录到undo段中)

(索引的维护也是很高的,比如要更新有索引的列 那么会生成好几倍的undo)

 

commit的开销主要来自两方面:

第一:客户端与数据库直接往返通信量将会显著增大

第二:每次提交,都必须等待redo写至磁盘(在这种情况下,就会出现log file sync的等待事件)

 

执行commit时,剩下的工作:

1、为事务生成一个SCN号

2、LGWR将所有未写入磁盘的重做日志条目写至磁盘,并把SCN记录到在线重做日志文件中;

3、v$lock中会记录着我们的回话锁,这些锁都将被释放,而排队等待这些锁的会话都会被唤醒,从而可以继续完成他们的工作;

4、如果事务修改的某些块还在缓冲区缓存中,Oracle就会以一种快速的模式访问并清理;

 

redo  与 undo 日志的主要区别:

1、undo日志:在恢复时取消未完成事务的影响,忽略已经提交的事务

2、redo日志:忽略未完成的事务,重做已经提交事务的改变。

3、undo日志:先将修改后的数据写到磁盘——写commit到磁盘

4、redo日志:先写commit到磁盘——将修改后的数据写到磁盘

5、undo日志:要求数据在事务结束后立即写到磁盘,可能增加磁盘IO数

6、redo日志:要求我们在事务提交和日志记录刷新以前将所有修改过的块保留在缓冲区,可能增加事务需要的平均缓冲区数

 

《临时表和redo、undo》

 

在12C之前:

临时表的数据块不会生成redo,因此,临时表的操作不是可恢复的。不过临时表会生成undo,而且这个undo会计入日志,因此,临时表也会生成一些redo;临时表可以有约束,也可以这么说:正常表有的一切临时表都可以有;

 

临时表的DML操作,有如下特点:

1、insert会生成很少甚至不生成undo  redo

2、临时表的update会生成永久表update大约一半的redo

3、delete在临时表上生成的redo与永久表上生成的redo同样多;

(临时表delete会生成很多redo,所以要避免进行delete操作,可以truncate;可以使用临时表进行insert和select操作)

 

在12C之后:

从Oracle12C起,我们可以通过设置temp_undo_enabled来将临时表的undo放在临时表空间中,由于临时表空间的任何数据变更都不会生成redo,所以当这个参数设置为TRUE时,任何临时表上的DML都会生产很少甚至不会产生redo;

(temp_undo_enabled的默认值是FALSE,如果将其改为TRUE的话,那临时表生成的redo量与12C版本之前是一样的)

 

ORA-01555: snapshot too old: -----这个错误是非常典型的错误:(它算的上是一个安全的错误,唯一的影响就是收到这个错误的查询无法继续处理)

产生这个错误的原因:

1、undo段太小,不足以支撑系统上执行的工作

2、程序夸commit获取数据

3、块清除

4、commit提交太频繁

 

解决的方法参考:

1、适当的设置参数undo_retention(要大于运行时间最长的事务所需的时间),我们可以通过v$undostat 来确定长时查询的持续时间,另外,请在磁盘上预留足够的空间,因为为了确保undo_retention,undo段可能也会有所增长;

2、使用手动undo管理时加大或增加更多的undo段,(不建议采用这种方法,强烈建议采用自动undo管理方式)

3、减少查询的运行时间(调优)。调优sql语句、

4、收集相关对象的统计信息。

 

转载于:https://blog.51cto.com/fengfeng688/1934429

标签:undo,生成,Oracle,日志,redo,重做
From: https://www.cnblogs.com/redarmy/p/17640735.html

相关文章

  • 【Oracle RAC Database】通过ASMLIB创建ASM DISK
    [root@node01~]#groupadd-g1200dba[root@node01~]#groupadd-g1201oinstall[root@node01~]#groupadd-g1202asmadmin[root@node01~]#groupadd-g1203asmdba[root@node01~]#useradd-u1100-goinstall-Gasmadmin,asmdba,dbagrid[root@node01~]......
  • 【Oracle RAC Database】通过DNS实现SCAN VIP的域名解析
    [root@node04~]#yuminstall-ybind[root@node04~]#vim/etc/named.confoptions{listen-onport53{192.168.1.104;};/*listen-on-v6port53{::1;};*/directory"/var/named";dump-file"/v......
  • Oracle学习记录
    Oracle学习记录查询表中所有列名SELECTCOLUMN_NAMEFROMUSER_TAB_COLUMNSWHERETABLE_NAME='MT_DATA_RECORD_ALL'时间比较比较两个日期是否相等SELECT*FROMyour_tableWHEREdate_column=TO_DATE('2022-01-01','YYYY-MM-DD');比较日期是否在某个......
  • Oracle VM VirtualBox 安装 centos7(最新)
    注意:重启或者从睡眠中唤醒虚拟机后,要systemctlrestartnetwork前期准备下载:http://www.oracle.com/technetwork/cn/server-storage/virtualbox/downloads/index.html 安装:https://blog.csdn.net/maty_wang/article/details/79127718 桥接、host-only、natnetwork的区别:ht......
  • Kettle 连接失败 Oracle 数据库报 ora-12505 的解决方法(转)
      用kettle新建DB连接的时候总是报错,可是用plsql连接是可以连上,错误信息大致如下:错误连接数据库[MIS]:org.pentaho.di.core.exception.KettleDatabaseException:ErroroccuredwhiletryingtoconnecttothedatabaseErrorconnectingtodatabase:(usingclassorac......
  • Oracle DB :用户自定义数据类型
    用户自定义类型可以使用Oracle内嵌的数据类型和其他用户自定义类型作为对象类型的构建块,对象模型构成了在应用中数据的结构和行为。下面将描述用户自定义类型的种类。提示:可以参考createType和createtypebody获取更多的创建用户定义数据类型的信息;==对象类型==对象类型是真......
  • 数据库管理系统——Oracle
    学习视频:01-day01-oracle-数据库相关概念介绍_哔哩哔哩_bilibili Oracle管理系统的介绍Oracle数据库的数据管理(增删改查)Oracle账户管理Oracle二维表管理 Oracle是市场上目前很流行的大型数据库,适用于大型项目的数据存储。合理的管理数据的存储和读取。 软件的安装和卸......
  • Oracle物化视图-看这一篇就可以了
    本文转载自:https://zhuanlan.zhihu.com/p/93081881 一、物化视图的创建creatematerializedview[view_name]refresh[fast|complete|force][on[commit|demand]|startwith(start_time)next(next_time)]as{创建物化视图用的查询语句} 具体实例如下: CREATE......
  • oracle10g分区表(一)
    一、创建分区表createtablelj_test_part(birthdatedate,agenumber(18,2))PARTITIONBYlist(birthdate)(partitionpart_t01values(to_date('2018-01-01','yyyy-mm-dd')),partitionpart_t02values(to_date('2018-01-02',&......
  • Oracle-RAC监听状态查看
    监听状态的查看,我们一般使用如下命令:lsnrctlstatus但是,这样一般查看到的是默认listener的状态,其他listener的状态需要,使用用如下命令:lsnrctlstatuslistener2lsnrctlstatuslistener_scan1那么,集群监听资源的状态如何查看呢?命令如下:[grid:rac01]:/home/grid>srvctlstatus......