Undo segment:
我的Oracle 9i学习日志(14)-- undo数据
原创
©著作权归作者所有:来自51CTO博客作者d185740815的原创作品,请联系作者获取转载授权,否则将追究法律责任
图1
用于保存一个进程修改了的数据的旧值。Undo segment头部包含记录了当前事务使用的undo segment信息的一张表。一系列事务只使用一个undo segment存储所有数据。许多并发的事务可以使用同一个undo segment。
Undo segment目的:事务回滚、事务恢复、读一致性。
读一致性:
图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语句为例。
图三
在开始执insert时,Oracle在内存里产生相应的数据信息、undo信息,并且无论是数据,索引还是undo都会产生redo。如果这时突然断电或crash,内存内的数据丢失,但磁盘文件没有被修改。下次启动时不要进行恢复操作。
图四
在把要插入的数据写入磁盘文件之前,先写redo。这时如果crash了,下次启动将根据redo恢复数据。以下的updata操作也是同理。
图五---图六
Undo segment类型:
System undo segment:存在system表空间里,system表空间专用。
Non-system undo segment:在存在多个表空间的数据库里,至少需要一个non-system undo segment,或手动方式管理或自动方式管理。其中手动方式管理的undo segment又分为private undo segment和public undo segment两种;自动管理方式必须存在一个活动的undo tablespace。
Deferred undo segment:当表空间脱机时可能会创建deferred undo segment用于在表空间恢复联机时回滚事务。由Oracle server自动管理。
自动undo segment管理:
Undo data在undo表空间中被自动管理,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 backup和end 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.
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
我的PHP8编译日志
PHP8编译命令
PHP 编译