撤销表空间(UNDO表空间)用于存储撤销信息,当执行DML操作(INSERT、UPDATE和DELETE等)时,Oracle会将这些操作的旧数据(即撤销信息)写入UNDO段中,而UNDO段驻留在UNDO表空间中。
1. 撤销表空间的作用
撤销表空间,通常也被称为UNDO表空间。UNDO表空间中的段被称为撤销段或UNDO段。撤销段中存储的数据就是撤销信息,这些撤销信息也被称为撤销数据或UNDO数据。撤销段的几种作用如下:
1.1. 使读写一致
在不同的进程或用户模式下检索数据时,Oracle只能给用户提供被提交的数据,这样可以确保数据的一致性。例如,首先在scott模式下,执行UPDATE emp SET sal=5500 WHERE empno=7788语句,这样旧的数据记录会被存储到UNDO段中,而新数据则会被存储到emp段中,假定此时该数据尚未提交(如没有执行COMMIT命令,也没有退出SQL* Plus环境)。然后用户在system模式下执行SELECT sal FROM scott.emp WHERE empno=7788语句,此时用户将取得旧的工资数据,而不是新数据5500,而该数据正是从UNDO段中读取的。
1.2. 回退事务
当执行修改(UPDATE)数据操作时,旧的数据(即UNDO数据)被存储到UNDO段,而新的数据则会被存储到数据段中。如果在修改操作中事务提交出现错误,就需要回退事务,从而取消数据的更改。例如,当用户使用UPDATE语句修改员工的工资时,发现原本打算修改某个人的工资,但由于误操作,而导致修改了全公司员工的工资(如没有使用WHERE条件语句)。这样,用户就可以通过执行ROLLBACK语句来取消事务修改。当执行ROLLBACK语句时,Oracle会将UNDO段的UNDO数据(即旧的员工工资)全部写回数据段中。
1.3. 事务恢复
事务恢复是例程恢复的一部分,它是由Oracle服务器自动完成的。如果在数据库运行过程中出现例程失败(如断电、内存故障等),那么当重启Oracle服务器时,后台进程SMON会自动执行例程恢复。执行例程恢复时,Oracle会重新处理所有未提交的数据记录,回退未提交事务。
1.4. 闪回操作
Oracle具有强大的闪回功能,其中很多闪回技术都是基于UNDO段实现的,如闪回表、闪回事务查询、闪回版本查询等。
2. 撤销表空间的初始化参数
Oracle可以通过设置初始化参数来控制UNDO表空间管理撤销数据,与UNDO表空间有关的参数有以下几种:
UNDO_TABLESPACE:该初始化参数用于指定例程所要使用的UNDO表空间,使用自动UNDO管理模式时,通过配置该参数可以指定例程所要使用的UNDO表空间。 UNDO_MANAGEMENT:该初始化参数用于指定UNDO数据的管理模式,如果为AUTO,则为自动撤销管理模式;如果为MANUAL,则为回滚段管理模式。需要注意的是,使用自动撤销管理模式时,如果没有配置初始化参数UNDO_TABLESPACE,则Oracle会自动选择第一个可用的UNDO表空间存储UNDO数据;如果没有可用的UNDO表空间,则Oracle会使用SYSTEM回滚段存储UNDO记录,并在ALTER文件中记载警告。 UNDO_RETENTION:该初始化参数用于控制UNDO数据的最大保留时间,默认为900 s。从Oracle 9i版本开始,通过配置该初始化参数,可以指定UNDO数据的保留时间,从而也决定了基于UNDO数据的闪回操作能够闪回的最早时间点。
想要查询当前实例所设置的UNDO表空间的参数,可以通过SHOW PARAMETER命令来查询。
3. 撤销表空间的基本操作
撤销表空间的基本操作包括创建、修改、切换和删除等。
3.1. 创建UNDO表空间
创建UNDO表空间需要使用CREATE UNDO TABLESPACE语句。
创建一个撤销表空间,并指定数据文件大小为100 MB,代码如下:
create undo tablespace undo_tbs_1 datafile '/opt/oracle/oradata/ORCLCDB/undotbs1.dbf' size 100M;
在创建UNDO表空间时,需要注意以下两方面:
UNDO表空间对应的数据文件大小通常由DML操作可能产生的最大数据量来确定,通常该数据文件的大小应在1 GB以上。 由于UNDO表空间只用于存储撤销数据,所以不要在UNDO表空间内建立任何数据对象(如表、索引等)。
3.2. 修改UNDO表空间
与修改普通的永久表空间类似,修改UNDO表空间也使用ALTER TABLESPACE语句。当事务用尽了UNDO表空间后,可以使用ALTER TABLESPACE…ADD DATAFILE语句添加新的数据文件;当UNDO表空间所在的磁盘被填满时,可以使用ALTER TABLESPACE…RENAME DATAFILE语句将数据文件移动到其他磁盘上;当数据库处于ARCHIVELOG模式时,可以使用ALTER TABLESPACE… BEGIN BACKUP/END BACKUP语句备份UNDO表空间。
向表空间undo_tbs_1中添加一个新的数据文件,指定该文件大小为2 GB,代码如下:
alter tablespace undo_tbs_1 add datafile '/opt/oracle/oradata/ORCLCDB/undotbs_add.dbf' size 2g;
3.3. 切换UNDO表空间
启动例程并打开数据库后,同一时刻指定例程只能使用一个UNDO表空间,切换UNDO表空间是指停止例程当前使用的UNDO表空间,并启动其他UNDO表空间。
把当前系统的默认UNDO表空间切换到自定义撤销表空间undo_tbs_1,代码如下:
alter system set undo_tablespace=undo_tbs_1;
通常情况下,Oracle默认的UNDO表空间是UNDOTBS1。
3.4. 删除UNDO表空间
如果某个自定义的UNDO表空间确定不再被使用,那么就可以将其删除。删除UNDO表空间与删除普通的永久表空间一样,都使用DROP TABLESPACE语句。
需要注意的是,当前例程正在使用的UNDO表空间是不能被删除的,如果确定要删除当前例程正在使用的UNDO表空间,应首先切换UNDO表空间,然后删除切换掉的UNDO表空间。
首先把当前例程的UNDO表空间从undo_tbs_1切换到undotbs1,然后删除undo_tbs_1表空间,代码如下:
--将UNDO表空间切换到undotbs1
alter system set undo_tablespace=undotbs1;
--删除undo_tbs_1表空间
drop tablespace undo_tbs_1;
3.5. 查询UNDO表空间的信息
经常需要查询的UNDO表空间信息主要有以下几种:
①查询当前例程正在使用的UNDO表空间的信息
对于当前例程正在使用的UNDO表空间的信息,可以通过查询初始化参数undo_tablespace来实现查看。
--查看当前实例正在使用的UNDO表空间
show parameter undo_tablespace;
②查询实例的所有UNDO表空间的信息
对于实例的所有UNDO表空间可以通过查询数据字典dba_tablespaces来实现查看。
--查询当前实例拥有的所有UNDO表空间
select tablespace_name from dba_tablespaces where contents = 'UNDO';
③查询UNDO表空间的统计信息
使用自动UNDO管理模式时,需要合理设置UNDO表空间的大小,为了合理规划UNDO表空间的大小,应在数据库运行的高峰期搜集UNDO表空间的统计信息,最终根据该统计信息来确定UNDO表空间的大小。通过查询动态性能视图v$undostat可以搜集UNDO统计信息。
--统计UNDO表空间中“回退块”的生成信息
select to_char(begin_time,'hh24:mi:ss') as 开始时间,to_char(end_time,'hh24:mi:ss') as 结束时间,undoblks as 回退块数 from v$undostat order by begin_time;

④查询UNDO段的统计信息
使用自动UNDO管理模式时,Oracle会在UNDO表空间上自动建立10个UNDO段。若要显示所有联机UNDO段的名称,可以通过查询动态性能视图vrollstat来实现。如果在vrollstat之间执行连接查询,则可以监视特定UNDO段的特定信息。
通过动态性能视图监视特定UNDO段的信息,包括段名称、活动事务个数和段中的扩展个数等信息,代码如下:
select rn.name,rs.xacts,rs.writes,rs.extents from v$rollname rn,v$rollstat rs where rn.usn = rs.usn;

上图中,NAME列用于标识UNDO段的名称,XACTS列用于标识UNDO段所包含的活动事务个数,WRITES列用于标识在UNDO段上写入的字节数,EXTENTS列用于标识UNDO段的区个数。
⑤查询活动事务信息
当执行DML操作时,Oracle会将这些操作的旧数据放到UNDO段中。如果要显示会话的详细信息,则可以使用动态性能视图vtransaction;如果要显示联机UNDO段的名称,则可以使用v$rollname动态性能视图。
--通过查询v$transaction动态性能视图来显示事务的名称和状态
select name,status from v$transaction;
⑥查询UNDO区信息
在数据字典dba_undo_extents中,可以查询UNDO表空间中所有区的详细信息,包括UNDO区的大小和状态等信息。
在dba_undo_extents数据字典中,查询指定段的信息,包括段编号、段的大小和段的状态等,代码如下:
select segment_name, extent_id,bytes,status from dba_undo_extents where segment_name='_SYSSMU7_2728255665$';

上图中,SEGMENT_NAME列用于标识指定的段名称,EXTENT_ID列用于标识区编号,BYTES列用于标识区尺寸,STATUS列用于标识区状态(ACTIVE表示该区处于活动状态,EXPIRED表示该区未用)。
今天的文章就到这里,如果对你有用,记得点个【赞】和【在看】,感谢阅读~




