您的位置:首页 > 数据库 > Oracle

Oracle 11g undo 管理

2014-11-22 15:00 435 查看
oracle 11g undo 介绍: http://blog.csdn.net/dataminer_2007/article/details/41213945
undo 是 oracle 数据库中一个非常重要的机制, 在对数据库进行数据修改的时候, 能够为修改的数据构造一种前镜像数据(保存修改之前的旧值), 用来保证回滚对数据库的修改以及对多个用户同时访问的数据提供一致性读. 此外, undo 对于恢复数据库以及 flashback 查询之前时间的数据有着至关重要的作用,

1. undo 相关的数据字典

1.1 v$undostat:

displays a histogram of statistical data to show how well the system is working. The available statistics include undo space consumption, transaction concurrency, and length of queries executed in the instance. You can use this view to estimate the amount
of undo space required for the current workload. Oracle uses this view to tune undo usage in the system. The view returns NULL values if the system is in manual undo management mode.

显示最近一段时间内关于 undo 表空间使用情况的统计信息, 可以用这个 view 来优化系统, 每隔 10 分钟自动增加一条数据, 总共只保存四天的数据, 如果要查询超过四天的数据就要使用 dba_hist_undostat, 这个 view 仅对于自动 undo 管理模式有效.

几个重要的字段说明:

UNDOTSNNUMBER最近活动的 undo 表空间的 id
UNDOBLKSNUMBER当前时间段内消耗的 undo blocks 总数
TXNCOUNTNUMBER当前时间段内执行的事务总数
MAXQUERYLENNUMBER当前时间段内执行单个查询花费的最长时间, 单位为秒
MAXQUERYIDNUMBER当前时间段内执行单个查询花费的最长时间的 sql id
UNXPSTEALCNTNUMBER其他事务尝试盗用未过期 undo 回滚段的次数
UNXPBLKRELCNTNUMBER其他事务已经盗用未过期 undo 回滚段的数量
UNXPBLKREUCNTNUMBER未过期的 undo 回滚段重用的数量
EXPSTEALCNTNUMBER尝试盗用已经过期回滚段的次数
EXPBLKRELCNTNUMBER已经盗用过期回滚段的数量
EXPBLKREUCNTNUMBER已经过期回滚端重用的数量
SSOLDERRCNTNUMBER返回 ora-01555 错误的次数, 如果 SSOLDERRCNT 大于 0, 说明 undo_retention 设置有问题, 需要增加 undo_retention 的大小
NOSPACEERRCNTNUMBER空间不足申请新的 undo 表空间的次数
TUNED_UNDORETENTIONNUMBER已提交数据的undo 数据过期时间, 单位为秒 , 对于估计 flashback 可用的时间有用
SQL> select UNDOTSN, UNDOBLKS, TXNCOUNT, MAXQUERYLEN, MAXQUERYID, UNXPSTEALCNT, UNXPBLKRELCNT, UNXPBLKREUCNT, EXPSTEALCNT, EXPBLKRELCNT, EXPBLKREUCNT, SSOLDERRCNT, NOSPACEERRCNT, TUNED_UNDORETENTION

from v$undostat;

1.2 dba_hist_undostat

显示所有的 v$undostat 的历史记录

1.3 dba_undo_extents:

显示数据库所有 undo 表空间的回滚段情况, 其中 status 的取值为 EXPIRED / UNEXPIRED / ACTIVE

Active: 活动状态, 说明当前这个回滚段被某个事务正在使用, 不会被其他事务使用

Expired: 已经过期, 随时可以被其他事务使用

Unexpired: 没有过期, 为了 undo_retention 的需要保留在 undo 表空间, 当空间不足时有可能被其他事务使用

1.4 v$rollname:

只有两个字段(usn, name), 就是一个回滚段 id 和 name, 通常和 v$rollstat 一起使用

1.5 v$rollstat:

统计回滚段表的使用情况

其中 xacts 表示当前回滚段上存在的活动事务的数量

status 的取值为 ONLINE / PENDING OFFLINE / OFFLINE / FULL

SQL> select a.usn, a.name, b.rssize, b.writes, b.xacts, b.waits, b.extends, b.status

from v$rollname a, v$rollstat b

where a.usn = b.usn;

1.6 dba_rollback_segs:

显示所有回滚段(包括 SYS 和 PUBLIC)的空间分配情况及当前状态

其中 status 的取值为 OFFLINE / ONLINE / NEEDS RECOVERY / PARTLY AVAILABLE / UNDEFINED

SQL> select owner, segment_name, tablespace_name, initial_extent, next_extents, status

from dba_rollback_segs;

2. Undo 表空间管理

2.1 undo 回滚段

在自动管理的 undo 表空间下, 数据库创建时会自动初始化 10 个回滚段, 从 v$rollname 中可以查询到这些自动创建的回滚段信息, 此外, oracle 会根据系统的负载情况自动创建以及释放回滚段.

众所周知, 回滚段保存的是修改的数据的前镜像数据, 对于 DML(insert, update, delete) 语句来说, 回滚段保存的就是 DML 反向操作的数据, 如果是 insert 插入一行数据, 回滚段保存的就是删除该行的记录, 为了节约空间精简数据, 回滚段中只保存 insert 数据的 rowid, undo 只需要删除该 rowid 的记录即可;如果是 update 数据, 回滚段只保存修改字段的旧值, undo 只需要把旧值覆盖即可;如果是
delete 数据, 回滚段则需要保存整行的数据, undo 只需要把整行的数据插入即可.

由此可知, delete 操作产生的 undo(回滚段) 数据最多, 对于大批量的删除必定会对 undo 表空间产生比较大的冲击, 由此, 如果是删除整个表的数据可以用 truncate; 如果不是整个表的数据, 可以把分批删除数据.

回滚段的大小和数量对于系统至关重要, 所有 online 的回滚段(除了 system 的回滚段)都会被循环使用. 而每个回滚段都包含有一些 extent(扩展), 当某个 extent 写满后会自动切换到另一个 extent 继续使用.

2.2.2 undo 数据重用

对于自动扩展的 undo 表空间, oracle 会根据 undo_retention 的值作为保留 undo 数据的最少时间. 而对于固定大小又非 guarante 的 undo 表空间, oracle 会根据 undo 表空间大小及 v$undostat 的统计信息自动调整 以最大可能的保留 undo 数据, 这种情况下设置的 undo_retention 设置将被忽略. 此外, 如果 undo 表空间不足且无法自动扩展时, undo_retention
设置也将被忽略, 因为为了满足系统事务需求, 一些状态为 unexpired 的 undo 数据也有可能被置换重用.

当一个正在执行的事务需要更多 undo 空间,而 undo 表空间不足且无法扩展时, oracle 优先会重用当前回滚段下状态为 expired 的 undo extents, 如果没有就去其他回滚段下状态为 expired undo extents, 如果没有再回到当前回滚段中查找状态为 unexpired 的 undo extents, 如果还没有再去查找其他回滚段中状态为 unexpired 的 undo extents, 如果还没有就报空间不足的错误消息.

因此, 如果 undo_retention 为 900 秒(默认值), 并不一定意味着 undo 数据在 undo 表空间中保存 900 秒, 因为如果空间不足就会去覆盖不管是否已经 expired 的 已提交事务的undo 数据. 此外, undo_retention 时间到了之后, 并不一定意味这些 undo 数据在 undo 表空间中消失, 它只是并标示为 expired, 只要没有被其他事务的 undo 数据覆盖, 它会依然存在.

总之, 对于自动管理的 undo 表空间, 我们依然每天要对它进行巡检, 保证 undo 表空间有足够的存储空间.

2.3 日常监控 undo 表空间

SQL> show parameter undo

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

undo_management string AUTO

undo_retention integer 900

undo_tablespace string UNDOTBS1

查看当前 undo 表空间大小

SQL> select sum(bytes)/1024/1024 "Current Undo Size(M)" from dba_data_files where tablespace_name='UNDOTBS1';

Current Undo Size(M)

------------------------------

10

查看当前 undo 表空间使用情况

SQL> select owner, segment_name, bytes/1024/1024 from dba_segments where tablesp

ace_name='UNDOTBS1';

OWNER SEGMENT_NAME BYTES/1024/1024

------------------------------ ------------------------------ --------------------------------------

SYS _SYSSMU20_781529403$ .3125

SYS _SYSSMU19_381980475$ .1875

SYS _SYSSMU18_53648357$ .1875

SYS _SYSSMU17_3412666006$ .3125

SYS _SYSSMU16_2828248073$ .3125

SYS _SYSSMU15_461690133$ .1875

SYS _SYSSMU14_3296674710$ .375

SYS _SYSSMU13_2498580566$ .25

SYS _SYSSMU12_2686240293$ .1875

SYS _SYSSMU11_103500371$ .125

10 rows selected.

SQL> select tablespace_name, status, sum(bytes)/1024/1024 from dba_undo_extents

group by tablespace_name, status;

TABLESPACE_NAME STATUS SUM(BYTES)/1024/1024

------------------------------ --------- ----------------------------------------------

UNDOTBS1 UNEXPIRED 1.5625

UNDOTBS1 EXPIRED .75

查看当前谁占用了 undo 表空间

SQL> select r.name "undo tablespace name",

rssize / 1024 / 1024 / 1024 "rssize(G)",

s.sid,

s.serial#,

s.username "username",

s.status,

s.sql_hash_value,

s.sql_address,

s.machine,

s.module,

substr(s.program, 1, 78) "program",

r.usn,

hwmsize / 1024 / 1024 / 1024,

shrinks,

xacts

from sys.v_$session s,

sys.v_$transaction t,

sys.v_$rollname r,

v$rollstat rs

where t.addr = s.taddr

and t.xidusn = r.usn

and r.usn = rs.usn

order by rssize desc;

2.3 切换 undo 表空间

SQL> create undo tablespace undo_david datafile 'g:\oracle\oradata\bakdb\undo_da

vid.dbf' size 10M;

Tablespace created.

SQL> alter system set undo_tablespace='undo_david' scope=both;

System altered.

SQL> show parameter undo

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

undo_management string AUTO

undo_retention integer 900

undo_tablespace string undo_david

SQL> select segment_name, tablespace_name, status from dba_rollback_segs;

SEGMENT_NAME TABLESPACE_NAME STATUS

------------------------------ ------------------------------ ----------------

SYSTEM SYSTEM ONLINE

_SYSSMU1_719184344$ UNDOTBS1 OFFLINE

_SYSSMU2_2817567661$ UNDOTBS1 OFFLINE

_SYSSMU3_3680621135$ UNDOTBS1 OFFLINE

_SYSSMU4_237230745$ UNDOTBS1 OFFLINE

_SYSSMU5_2985270510$ UNDOTBS1 OFFLINE

_SYSSMU6_2775061352$ UNDOTBS1 OFFLINE

_SYSSMU7_3717448562$ UNDOTBS1 OFFLINE

_SYSSMU8_1685456424$ UNDOTBS1 OFFLINE

_SYSSMU9_2264502008$ UNDOTBS1 OFFLINE

_SYSSMU10_1467141425$ UNDOTBS1 OFFLINE

SEGMENT_NAME TABLESPACE_NAME STATUS

------------------------------ ------------------------------ ----------------

_SYSSMU11_103500371$ UNDO_DAVID ONLINE

_SYSSMU12_2686240293$ UNDO_DAVID ONLINE

_SYSSMU13_2498580566$ UNDO_DAVID ONLINE

_SYSSMU14_3296674710$ UNDO_DAVID ONLINE

_SYSSMU15_461690133$ UNDO_DAVID ONLINE

_SYSSMU16_2828248073$ UNDO_DAVID ONLINE

_SYSSMU17_3412666006$ UNDO_DAVID ONLINE

_SYSSMU18_53648357$ UNDO_DAVID ONLINE

_SYSSMU19_381980475$ UNDO_DAVID ONLINE

_SYSSMU20_781529403$ UNDO_DAVID ONLINE

21 rows selected.

SQL> select usn,xacts,status from v$rollstat;

USN XACTS STATUS

---------- ---------- ---------------

0 0 ONLINE

11 0 ONLINE

12 0 ONLINE

13 0 ONLINE

14 0 ONLINE

15 0 ONLINE

16 0 ONLINE

17 0 ONLINE

18 0 ONLINE

19 0 ONLINE

20 0 ONLINE

11 rows selected.

要等到旧的 undo 表空间 undotbs1 上的回滚段都 offline 后才能 drop

SQL> drop tablespace undotbs1;

Tablespace dropped.

SQL> select tablespace_name, file_name, status from dba_data_files where tablesp

ace_name like 'UNDO%';

TABLESPACE_NAME FILE_NAME STATUS

------------------------------ ------------------------------ --------- ----------------------------------------------------------

UNDO_DAVID G:\ORACLE\ORADATA\BAKDB\UNDO_DAVID.DBF AVAILABLE

虽然 drop 成功, 但是如果有其他查询需要用到旧的 undo 表空间 undotbs1 上的数据时就会提示 ora-01555 的错误

SQL> select * from dba_undo_extents where tablespace_name='UNDOTBS1';

总之, 切换系统当前 undo 表空间到新建的 undo 表空间几乎可以随时执行成功, 但是如果要删除旧的 undo 表空间一定要等到该 undo 空间里所有的回滚段全部 offline. 千万别在尚有回滚段处于 online 状态强制删除数据文件.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: