Undo segment

 

 我的Oracle 9i学习日志(14)-- undo数据_Oracle

1
用于保存一个进程修改了的数据的旧值。Undo segment头部包含记录了当前事务使用的undo segment信息的一张表。一系列事务只使用一个undo segment存储所有数据。许多并发的事务可以使用同一个undo segment
Undo segment目的:事务回滚、事务恢复、读一致性。
读一致性
 

 我的Oracle 9i学习日志(14)-- undo数据_笔记_02

2
每个事务都会分配一个SCN(system change number)SCN序号只会增大。当一个查询事务开始时,系统将分配一个比将要查询的表中的SCN都大的一个SCN。在查表时如果碰到比事务SCN大的记录,就会去undo segment里查询相应的旧的记录。如果因为时间查询时间太长或其他原因,旧的记录在undo segment里被覆盖了的话,查询将失败。
实验:
luo用户在第一个终端登录:
SQL> select * from test;
 
        ID NAME
---------- --------------------
         0 hello
SQL> insert into test values(1, 'world');
 
1 row created.
SQL> select * from test;
 
        ID NAME
---------- ----------
         0 hello
         1 world
luo在第二个终端登录:
SQL> select * from test;
 
        ID NAME
---------- --------------------
         0 hello
返回第一个终端:
 
SQL> commit;
 
Commit complete.
第二个终端:
SQL> select * from test;
 
        ID NAME
---------- --------------------
         0 hello
         1 world
Redo&undo
insert语句为例。
 

 我的Oracle 9i学习日志(14)-- undo数据_学习_03

图三
在开始执insert时,Oracle在内存里产生相应的数据信息、undo信息,并且无论是数据,索引还是undo都会产生redo。如果这时突然断电或crash,内存内的数据丢失,但磁盘文件没有被修改。下次启动时不要进行恢复操作。
 

 我的Oracle 9i学习日志(14)-- undo数据_职场_04

图四
在把要插入的数据写入磁盘文件之前,先写redo。这时如果crash了,下次启动将根据redo恢复数据。以下的updata操作也是同理。
 

 我的Oracle 9i学习日志(14)-- undo数据_Oracle_05

 

 我的Oracle 9i学习日志(14)-- undo数据_休闲_06

图五---图六
Undo segment类型:
System undo segment:存在system表空间里,system表空间专用。
Non-system undo segment:在存在多个表空间的数据库里,至少需要一个non-system undo segment,或手动方式管理或自动方式管理。其中手动方式管理的undo segment又分为private undo segmentpublic undo segment两种;自动管理方式必须存在一个活动的undo tablespace
Deferred undo segment:当表空间脱机时可能会创建deferred undo segment用于在表空间恢复联机时回滚事务。由Oracle server自动管理。
自动undo segment管理:
Undo dataundo表空间中被自动管理,DBA需根据数据库的负荷给出充足的表空间大小。
参数:
SQL> show parameter undo
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     10800
undo_suppress_errors                 boolean     FALSE
undo_tablespace                      string      UNDOTBS1
如果管理方式是auto并且只存在一个undo tablespace,那么undo_management 是可选项,the Oracle server will automatically choose the UNDO tablespace.
undo_retention的值决定了undo segment中的数据存储的最长时间,超过这个时间则可能会被其他undo数据覆盖。如果undo segment没有足够的空间,则undo数据即使没过期也可能会被覆盖。这时如果有查询语句可能会导致报错:ORA-1555 snapshot too old.
创建undo 表空间:
SQL> select tablespace_name, contents from dba_tablespaces;
 
TABLESPACE_NAME                CONTENTS
------------------------------ ---------
SYSTEM                         PERMANENT
UNDOTBS1                       UNDO
TEMP                           TEMPORARY
CWMLITE                        PERMANENT
DRSYS                          PERMANENT
EXAMPLE                        PERMANENT
INDX                           PERMANENT
ODM                            PERMANENT
TOOLS                          PERMANENT
USERS                          PERMANENT
XDB                            PERMANENT
 
TABLESPACE_NAME                CONTENTS
------------------------------ ---------
LUO                            PERMANENT
MYTEMP                         TEMPORARY
DATA02                         PERMANENT
INDEX01                        PERMANENT
RONLY                          PERMANENT
B4K                            PERMANENT
方法一:
CREATE DATABASE db01
. . .
UNDO TABLESPACE undo1 DATAFILE '/u01/oradata/undoldb01.dbf' SIZE 20M AUTOEXTEND ON
方法二:
CREATE UNDO TABLESPACE undo1 DATAFILE '/u01/oradata/undo1db01.dbf' SIZE 20M;
如果在create database时,undo_management参数指定为auto,但是又省略了undo tablespace的句子,那么Oracle会自动创建一个undo tablespace,命名为sys_undots,对应的数据文件:$ORACLE_HOME/dbs/dbu1sid.dbf.
 
改变undo表空间:
与其他表空间一样,undo表空间可以增删数据文件,重命名,数据文件离线与联机,begin backupend backup
切换undo表空间:
可以有多个undo表空间,但只有一个是活动的。命令:ALTER SYSTEM SET UNDO_TABLESPACE=UNDOTBS2;可以切换当前活动undo表空间。
注意:切换表空间后,如果原来的表空间中还有有用的数据,如:事务没用提交,那么原来的表空间还会被使用一段时间(可能是由于undo_retention的时间限制),直到所有数据无效。
SQL> select * from test ;
 
        ID NAME
---------- ----------
         0 hello
         1 world
 
SQL> insert into test values(2, 'aaa');
 
1 row created.
SQL> alter system set undo_tablespace='myundo1';
 
System altered.
SQL> commit;
 
Commit complete.
 
SQL> select * from test;
 
        ID NAME
---------- ----------
         0 hello
         1 world
         2 aaa
删除undo表空间:
如果undo表空间在使用,则不能被drop
Undo数据统计信息:
查看当前未提交事务占用的undo block数量:
SQL> select addr, used_ublk from v$transaction;
 
ADDR      USED_UBLK
-------- ----------
5AB34700          1
 
SQL> select begin_time,end_time, undoblks from v$undostat;
下面视图每十分钟记录一次这段时间内使用的undo block数量。
BEGIN_TIM END_TIME    UNDOBLKS
--------- --------- ----------
02-APR-10 02-APR-10         17
02-APR-10 02-APR-10         19
01-APR-10 02-APR-10         17
01-APR-10 01-APR-10         18
01-APR-10 01-APR-10         18
01-APR-10 01-APR-10         24
01-APR-10 01-APR-10         17
01-APR-10 01-APR-10         19
01-APR-10 01-APR-10         19
01-APR-10 01-APR-10         19
01-APR-10 01-APR-10         14
如果undo空间过小,当一个事务需要的undo空间不够时则事务处理失败。
估算undo tablespace大小:
三个参考值:(UR)undo_retention(UPS)每秒产生undo block的数量、(DBS)块大小。
估算每秒产生undo block块数量方法:
方法一:取最大值,
SQL> select max(undoblks / ((end_time - begin_time)*24*3600)) from v$undostat;
 
MAX(UNDOBLKS/((END_TIME-BEGIN_TIME)*24*3600))
---------------------------------------------
                                          .04
方法2:取平均值
SQL> select sum(undoblks) / sum((end_time - begin_time)*24*3600) from v$undostat;
 
SUM(UNDOBLKS)/SUM((END_TIME-BEGIN_TIME)*24*3600)
------------------------------------------------
                                      .030844624
Segment大小 = 每秒块数量*undo_retention*db_block_size
Undo配额:
须额外的包才能提供此功能。
相关视图:
 DBA_ROLLBACK_SEGS
 V$ROLLNAME
 V$ROLLSTAT
 V$UNDOSTAT
 V$SESSION
 V$TRANSACTION
练习:
1 Connect as user SYSTEM/MANAGER, and list the undo segments in tablespace UNDOTBS.
解析:SQL> select segment_name, tablespace_name from dba_rollback_segs;
 
2 Create undo tablespace UNDO2, size 15M, in $HOME/ORADATA/u03. List the undo
segments in tablespace UNDO2.
3 In a new telnet session start SQL*Plus and connect as user HR and run script
lab10_03.sql to insert a row into table DEPARTMENTS. Do not commit, roll back, or exit the session.
解析:见上次习题1.
 
4 In the session in which you are connected as SYS, using the ALTER SYSTEM command,switch the UNDO tablespace from UNDOTBS to UNDO2, using SCOPE=BOTH.
5 As SYS, drop tablespace UNDOTBS. Use the INCLUDING CONTENTS AND DATAFILES clause. What happened?
6 List the undo segments in tablespace UNDOTBS and their status. Compare this
list to the list in step 1.
Hint: Query DBA_ROLLBACK_SEGS data dictionary view.
7 In the session connected as HR, roll back the transaction and exit the session.
8 In the session connected as SYS, drop tablespace UNDOTBS. What happened?
9 As SYS, issue the following command:
ALTER SYSTEM SET undo_retention=0 SCOPE=memory;
Now drop tablespace UNDOTBS. What happened?
Note: There still may be a delay before the tablespace is dropped.