百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

一文看懂oracle数据库UNDO表空间是如何设计的

sinye56 2024-09-16 14:28 6 浏览 0 评论

概述

今天主要分享UNDO的一些作用及oracle是如何去设计并管理它的,大家一起看下吧~


01

UNDO的作用

1、作用

还原段的引入,主要是为了解决三个问题。

事务恢复:在进行DML操作时,insert、update、delete操作时,undo段记录事务的反向操作并且redo日志也记录undo段的操作,既redo保护undo段的信息。当实例关闭或意外崩溃后,再次open时实例需要对没有commit的事务进行回滚,完成事务的恢复。

事务回滚:用户进行DML操作后没有进行commit,需要修改前的数据。只要该操作在undo段保护的时间内,此时执行rollback操作可以回滚到最近记录点或上一次commit操作后的状态,恢复到数据修改前的状态。

读一致性:当进行DML操作时,undo段会记录数据变更前的状态(通过构造原数据的一致性数据块)。如果用户还没有进行commit操作,其他人查询此条数据会看到数据变更前的状态。因为其他用户读到的数据是undo段中原数据块中的数据,保证没有commit的数据读取的一致性。

2、读一致性

下面模拟复杂环境下,读一致性在复杂环境下如何能够保证?

1)会话A在9:50分的时候对T表发起了一次查询,需要10分钟完成查询结果打印。

2)会话B在9:51分对T表进行了一次update,并且commit。此时undo段会记录会话B在update的反向操作,假设名为undo1。

3)会话C在9:52分对T表进行了一次insert,并且同样commit。此时undo段会记录insert反向操作,假设名为undo2。

4)会话A的查询在发起时已经记录数据库当前的SCN号,假设此时SCN号为950。由于ILT事务槽记录最新的SCN号,所以再与数据块头部ILT事务槽中的SCN号进行比对时发现当前SCN大于950,所以需要对undo段进行查询。查询到undo2段信息进行比对发现SCN大于950,通过undo中记录的事务信息在进行前一个数据变更查找,此时undo1的SCN还是大于950,再继续查找前面的undo信息,发现undo0的SCN号比950要早,此时会将undo0记录的数据的信息+未变更的数据块信息打印给用户。

5)由于undo段是通过覆盖的方式进行记录的,如果时间过长或频繁进行DML操作。那么在寻找过程中可能会出现没有小于SCN号950的undo段,会返回一个经典错误ORA-1555 snapshoot too old(快照过旧),这样是为了避免幻影读、脏读等现象,保证读一致性的绝对特性。

通过上面的一个模拟,证明undo段不仅记录事务的回滚信息、同样记录ILT事务槽的上一次变更信息,并且保证能够通过不断读取undo段中记录ILT事务槽中的SCN号进行事务的历史查询。简单来讲只要UNDO段足够大,数据库中任何时间的DML操作都可以进行查询。


读一致性的具体步骤

  1. 确认读取时间的SCN号
  2. 搜索所有关联此表、行的数据块,要求数据块ILT事务槽的SCN号要小于读取时刻的SCN号。
  3. 如果搜索到小于读取时刻的SCN号,直接读取
  4. 如果全部没有小于读取时刻的SCN号,则根据数据块内ILT事务槽记录的undo信息,查找改变之前的数据。如果SCN号还是大于读取时刻,那么通过递归读取undo块所有关联这一事务的数据块,直至找到比读取时刻SCN号小undo块的信息,找到后进行读取。
  5. 如果没有比读取时刻的SCN号小的undo信息,那么报ORA-155错误。

3、实例恢复与事务回滚解析

实例恢复:在需要实例恢复时,oracle会读取UNDO段的头部信息的事务表,每一个事务是否commit的信息都会存储在事务表内。已经commit的事务不作处理,没有commit的事务会进行rollback的回滚处理完成事务回滚。防止脏数据的写入,造成脏读。

事务回滚:当需要回滚事务时,由于错误或者rollback命令都会产生回滚需求。此时根据ITL槽中记录的undo数据块地址找到undo块,进行数据的反向操作,从而实现恢复数据,即回滚事务。


02

UNDO参数的解析

1、UNDO_MANAGEMENT

该初始化参数用于指定UNDO数据的管理方式.如果要使用自动管理模式,必须设置该参数为AUTO,如果使用手工管理模式,必须设置该参数为MANUAL,使用自动管理模式时,oracle会使用undo表空间管理undo管理,使用手工管理模式时,oracle会使用回滚段管理undo数据,如果使用自动管理模式时,如果没有配置初始化参数UNDO_TABLESPACE。Oracle会自动选择第一个可用的UNDO表空间存放UNDO数据,如果没有可用的UNDO表空间,oracle会使用SYSTEM回滚段存放UNDO记录,并在ALTER文件中记载警告.

2、UNDO_TABLESPACE

该初始化参数用于指定例程所要使用的UNDO表空间,使用自动UNDO管理模式时,通过配置该参数可以指定实例所要使用的UNDO表空间.

在RAC(Real Application Cluster)结构中,因为一个UNDO表空间不能由多个实例同时使用,所有必须为每个实例配置一个独立的UNDO表空间.

3、undo_retention参数

在oracle 10g开始引入undo_retention参数,该参数是一个时间值。说明当还原段中的事务在提交后继续保留的时间,为flashback等工具进行如闪回数据等操作,该参数默认值为900秒,可以动态修改。

该参数以秒为单位,表示当事务提交或回滚以后,该事务所使用undo块里的数据能够提供的保留时间。当保留时间超过undo_retention所指定的时间以后,该undo块才能够被其他事务覆盖。当我们使用AUM的时候,并且设置了undo_retention以后,undo块的状态就会存在如下4种情况。

  • active:活跃的,表示正在使用该数据块的事务还没有提交或回滚。
  • inactive:不活跃的,表示该数据块上没有活动的事务,该状态的数据块可以被其他事务覆盖。
  • expired:达到时间上限的,表示该数据块持续inactive的时间已经超过了undo_retention所指定的时间,如果没有freed、inactive可以被其他事务覆盖。
  • freed:已经释放的,表示该数据块是空的,从来没有使用过。

在自动管理模式中,事务可以在不同的undo segment之间动态交换undo空间,也就是在不同的undo segment里交换extents。

当一个事务需要更多的undo空间的时候,如何进行处理?

当事务进行DML操作需要undo段进行事务保护时,首先获取undo表空间里可用的、空的extents(segment的最小分配单位是extent),获取其他undo segment里的expired状态的extents。

如果undo表空间内的数据文件启动了autoextensible(自动拓展),则数据文件会进行自动拓展。如果没有启动自动拓展,则获取undo segment里处于inactive状态的extent,如果没有此种状态的,会报ORA-30036(undo无法继续拓展)。

undo表空间获取空间的申请顺序

freed=>expired=>自动拓展(必须该参数为yes状态才可以)=>inactive(下面详细解释此种状态的覆盖)=>ORA-30036

而且在使用数据块时尽量使用相对更短的连续extent,如不足时才使用更连续的extent。这样能够减少碎片的产生。并且尽量不去覆盖inactive状态的数据块,如果空间足够会最大限度的保存此种状态的数据块包含的信息。


03

UNDO段的分类

1、分类

oracle中还原段共包含两大类,系统还原段和非系统还原段。

系统还原段为系统表空间使用,当系统表空间中的对象发生变化时,这些对象的原始值就保存在系统还原段中,系统还原段在系统表空间中创建,可以在自动模式和手动模式中。

非系统还原段为非系统表空间如用户表空间等所使用,当一个数据库系统具有非系统表空间时,就需要至少一个非系统还原段或一个自动管理的还原表空间,其中自动管理模式由数据库服务器自动维护,但需要至少一个还原表空间,而手动管理模式需要管理员创建非系统还原段,这些手动的非系统还原段分为两种类型,即公有还原段和私有还原段。

Oracle 9i以上版本都实现了还原段的自动管理,使用自动管理需要首先创建一个还原表空间,并通过还原表空间告诉数据库服务器,之后的管理工作都由数据库服务器自动完成。

2、还原段的自动管理

这里只涉及私有还原段的管理,即单实例UNDO段自动管理

在oracle 11g中通过两个参数来设置还原段的自动管理:

UNDO_MANAGEMENT(还原段的管理方式):此参数为静态参数需要设置后重启数据库才能生效。

UNDO_TABLESPACE(还原表空间的名字):此参数为动态参数设置完成可在数据库启动状态生效。


04

利用dba_undo_extents数据字典中查找undo段记录的原数据

该数据字典记录所有undo表空间记录undo段的分配信息,包括记录表空间的名字、段、区段、数据文件ID、数据块ID、retention保留状态等信息。

1、创建T表插入一行数据

create table t (id number,name varchar2(10));
insert into t values (1,'hwb');

2、查询此条更新记录回滚段的名字

select a.username,b.name,c.used_ublk from v$session a,v$rollname b,v$transaction c where a.saddr=c.ses_addr and b.usn=c.xidusn;
  • v$session:记录用户关于会话信息
  • v$rollname:记录回滚段的名字
  • v$transaction:记录关于事务的信息

3、通过查询到的回滚段名字,查询该回滚段在所在表空间、区段等信息

select segment_name,tablespace_name,extent_id from dba_undo_extents where segment_name='_SYSSMU3_2097677531
;

后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注一下~

相关推荐

Linux在线安装JDK1.8

首先在服务器pingwww.baidu.com查看是否可以连网然后就可以在线下载一、下载安装JDK1.81、在下载安装的同时做好一些准备工作...

Linux安装JDK,超详细

1、了解RPMRPM是Red-HatPackageManager(RPM软件包管理器)的缩写,这一文件格式名称虽然打上了RedHat的标志,但是其原始设计理念是开放式的,现在包括OpenLinux...

Linux安装jdk1.8(超级详细)

前言最近刚购买了一台阿里云的服务器准备要搭建一个网站,正好将网站的一个完整搭建过程分享给大家!#一、下载jdk1.8首先我们需要去下载linux版本的jdk1.8安装包,我们有两种方式去下载安装...

Linux系统安装JDK教程

下载jdk-8u151-linux-x64.tar.gz下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.ht...

干货|JDK下载安装与环境变量配置图文教程「超详细」

1.JDK介绍1.1什么是JDK?SUN公司提供了一套Java开发环境,简称JDK(JavaDevelopmentKit),它是整个Java的核心,其中包括Java编译器、Java运行工具、Jav...

Linux下安装jdk1.8

一、安装环境操作系统:CentOSLinuxrelease7.6.1810(Core)JDK版本:1.8二、安装步骤1.下载安装包...

Linux上安装JDK

以CentOS为例。检查是否已安装过jdk。yumlist--installed|grepjdk或者...

Linux系统的一些常用目录以及介绍

根目录(/):“/”目录也称为根目录,位于Linux文件系统目录结构的顶层。在很多系统中,“/”目录是系统中的唯一分区。如果还有其他分区,必须挂载到“/”目录下某个位置。整个目录结构呈树形结构,因此也...

Linux系统目录结构

一、系统目录结构几乎所有的计算机操作系统都是使用目录结构组织文件。具体来说就是在一个目录中存放子目录和文件,而在子目录中又会进一步存放子目录和文件,以此类推形成一个树状的文件结构,由于其结构很像一棵树...

Linux文件查找

在Linux下通常find不很常用的,因为速度慢(find是直接查找硬盘),通常我们都是先使用whereis或者是locate来检查,如果真的找不到了,才以find来搜寻。为什么...

嵌入式linux基本操作之查找文件

对于很多初学者来说都习惯用windows操作系统,对于这个系统来说查找一个文件简直不在话下。而学习嵌入式开发行业之后,发现所用到的是嵌入式Linux操作系统,本想着跟windows类似,结果在操作的时...

linux系统查看软件安装目录的方法

linux系统下怎么查看软件安装的目录?方法1:whereis软件名以查询nginx为例子...

Linux下如何对目录中的文件进行统计

统计目录中的文件数量...

Linux常见文件目录管理命令

touch用于创建空白文件touch文件名称mkdir用于创建空白目录还可以通过参数-p创建递归的目录...

Linux常用查找文件方法总结

一、前言Linux系统提供了多种查找文件的命令,而且每种查找命令都具有其独特的优势,下面详细总结一下常用的几个Linux查找命令。二、which命令查找类型:二进制文件;...

取消回复欢迎 发表评论: