扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
今天就跟大家聊聊有关undo表空间该怎么理解,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
公司主营业务:成都做网站、网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联推出云冈免费做网站回馈大家。
相关视图:
1、v$sysstat(查看用户提交数和回滚数)
SQL> SELECT name,value from v$sysstat where name like 'user %';
NAME VALUE
---------------------------------------------------------------- ----------
user commits 176
user rollbacks 0
user calls 328
user I/O wait time 3132
我们数据库中的awr报告中,Rollback per transaction %的值就是通过这两个值计算出来:
Round(User rollbacks/(user commit+user rollback),4)*100%
该指标数越接近于0说明数据库的回滚越少。
2、V$ROLLNAME:回滚段名称和回滚段ID信息。
对于回滚表空间,oracle默认会初始化10个回滚段,然后自动的分配或回收
3、V$ROLLSTAT:该视图保存着所有UNDO表空间中每一个已分配的回滚段当前状态以及相关的统计信息,不显示状态在OFFLINE的回滚段。
从v$rollstat中也可以看到对应的回滚段信息,XACTS是代表活动的事务。
USN:回滚段标识
RSSIZE:回滚段默认大小
XACTS:活动事务数
WRITES:回滚段写入数(单位:bytes)
SHRINKS:回滚段收缩次数
EXTENDS:回滚段扩展次数
WRAPS:回滚段翻转(wrap)次数
GETS:获取回滚段头次数
WAITS:回滚段头等待次数
SQL> select usn,writes,rssize,xacts,hwmsize,shrinks,wraps from v$rollstat;
USN WRITES RSSIZE XACTS HWMSIZE SHRINKS WRAPS
---------- ---------- ---------- ---------- ---------- ---------- ----------
0 7620 385024 0 385024 0 1
21 267816 2088960 0 2088960 0 0
22 36122 253952 1 253952 0 0
4、DBA_ROLLBACK_SEGS:此字典显示所有回滚段的当前状态以及与存储空间分配相关的信息,包括undo表空间的使用情况。
select segment_name,owner from dba_rollback_segs where tablespace_name='UNDOTBS3';
SEGMENT_NAME OWNER
------------------------------ ------
_SYSSMU21$ PUBLIC
_SYSSMU22$ PUBLIC
5、V$UNDOSTAT:保存了某一时间段的整个UNDO表空间使用的统计信息以及UNDO自动优化的结果,超出时间就会到DBA_HIST_UNDOSTAT中。
6、DBA_UNDO_EXTENTS:保存了UNDO表空间中所有已分配的数据区的存储空间分配情况与使用情况,是得到UNDO数据当前存在状态的一个重要的视图。
SQL> select tablespace_name,status,sum(bytes)/1024/1024/1024 from dba_undo_extents group by tablespace_name,status;
SQL> select owner,segment_name,extent_id,file_id,blocK_id from dba_undo_extents;
OWN SEGMENT_NAME EXTENT_ID FILE_ID BLOCK_ID
--- ------------------------------ ---------- ---------- ----------
SYS _SYSSMU20$ 0 9 153
SYS _SYSSMU20$ 1 9 161
SYS _SYSSMU19$ 0 9 137
7、V$TRANSACTION 当前正在进行事务的信息,与UNDO管理相关的是当前事务所涉及的UNDO段,UNDO空间占用等等信息
XIDUSN 表示回滚段号
XIDSLOT表示对应事务槽
START_UBABLK表示事务使用的undo起始block,
UBABLK 表示的是最后一个被使用的undo block,
XIDSQN 表示事务槽重用的递增序号
UBASQN 回滚段重用的递增序号
The slots in the transaction table in the undo segment header
are continuously being reused. Each time a slot it re-used,
its sequence number (xidsqn) goes up.(表示事务槽重用的递增序号)
Similarly, undo blocks are re-used (though it takes more
time to get round to re-using them than transaction slots).
Each time an undo block is "newed" and reused, its
sequence number UBASQN goes up.(回滚段重用的递增序号)
8、v$undostat
该视图可以用来查看回滚段开始使用时间和结束时间,回滚段被盗用的信息,空间不足,或ORA-01555错误发生等。
基本信息
•BEGIN_TIME:统计开始时间
•END_TIME:统计结束时间
使用信息
•UNDOTSN:最后报告的活动的UNDO表空间的ID。
•UNDOBLKS:期间产生的UNDO数据块的总数。
•TXNCOUNT:期间执行事务的总数。
•MAXQUERYLEN:期间完成的单个查询执行时间最长的长度,单位是秒。此时间计算方法是从游标打开到最后一次执行/提取数据所花费的时间。利用此时间可以调整相应的UNDO RETENTION。不过由于存在游标打开但是中间等待了很长时间没有操作之后再度取数据的情况,因此次数据也不一定准确。
•MAXQUERYID:上面所说查询的SQL ID。
•MAXCONCURRENCY:期间并发事务的最大数值。
未过期UNDO数据盗用信息
•UNXPSTEALCNT:期间发生的未过期UNDO数据盗用的次数。
•UNXPBLKRELCNT:期间发生的未过期UNDO数据被盗用数据块的数量。
•UNXPBLKREUCNT:期间发生的未过期UNDO数据盗用后被重用的数据块的数量。
已过期UNDO数据盗用信息
•EXPSTEALCNT:期间发生的盗用次数。
•EXPBLKRELCNT:期间发生的被盗用UNDO数据块数量。
•EXPBLKREUCNT:期间发生的被盗用数据块被重用的数量。
错误发生信息
•SSOLDERRCNT:期间ORA-1555错误发生次数。
•NOSPACEERRCNT:期间空间不足错误发生次数。
采样时UNDO数据使用信息
•ACTIVEBLKS:采样时刻活动的UNDO块数量。
•UNEXPIREDBLKS:采样时刻未过期的UNDO块数量。
•EXPIREDBLKS:采样时刻已过期的UNDO块数量。
自动UNDO优化结果
•TUNED_UNDORETENTION:UNDO表空间中不会被回收的UNDO数据到现在的时间,以秒计。通过查询这个字段我们能知道在之前某个特定时间完成的事务的UNDO数据是否还存在,对估计Flashback的可用时间很有帮助。
undo数据盗用是指undo数据在还没有过期的情况下,因为undo表空间大小或者undo_retention的设置等导致的数据块的被盗用,
可以分为未过期的undo数据盗用和已过期的undo数据盗用,所有的信息都可以在v$undostat视图中查看:
未过期UNDO数据盗用信息
UNXPSTEALCNT:期间发生的未过期UNDO数据盗用的次数。
UNXPBLKRELCNT:期间发生的未过期UNDO数据被盗用数据块的数量。
UNXPBLKREUCNT:期间发生的未过期UNDO数据盗用后被重用的数据块的数量。
已过期UNDO数据盗用信息
EXPSTEALCNT:期间发生的盗用次数。
EXPBLKRELCNT:期间发生的被盗用UNDO数据块数量。
EXPBLKREUCNT:期间发生的被盗用数据块被重用的数量。
相关的话,还有dba_extents,一张类似于dba_undo_extents的表,以及dba_esgments和dba_data_files,不过查询的时候需要指定undo表空间。
字典V$ROLLSTAT和V$UNDOSTAT在名字上面看起来有点相像,但是实际上这两个视图的差别还是很大的,V$ROLLSTAT记录的是整个UNDO表空间各个回滚段使用情况的统计,属于横向的;而V$UNDOSTAT记录的则是各个时间段上面整个UNDO使用情况的统计,属于纵向的。
一般来说,对于一个insert操作,由于只需记录插入的rowid所以产生的undo最少,而update操作,相对较多,而delete操作则花费最多的undo空间,一旦回滚,所需要的时间开销也最大。
oracle一方面不允许其他用户读取未提交数据,一方面要保证用户读取的数据要来自同一时间点。
undo表空间的几个参数:
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS3
undo_management:用来定义数据库使用的回滚段是使用自动管理方式还是手动管理方式(AUTO/MANUAL)
undo_tablespace:定义自动管理模式下,当前实例使用哪一个undo表空间。
undo_retention:在自动管理模式下,当回滚段状态为非激活时,回滚段的保留时间,默认900秒
undo_retention 只是指定undo 数据的过期时间,并不是说,undo 中的数据一定会在undo表空间中保存15 分钟,比如说刚一个新事务开始的时候,如果undo 表空间已经被写满,则新事务的数据会自动覆盖已提交事务的数据,而不管这些数据是否已过期,但是如果undo_retention的时间过了,那么已经提交的事务中的原数据就立刻不能访问了,但是他只是失效,只要没有被覆盖,他会仍然存在。
只有在一种情况下,undo 表空间能够确保undo 中的数据在undo_retention 指定时间过期前一定有效,就是为undo 表空间指定Retention 参数,指定之后,oracle 对于undo 表空间中未过期的undo数据不会覆盖,例如:
SQL> Alter tablespace undotbs1 retention guarantee;
禁止undo 表空间retention guarantee,例如:
SQL> Alter tablespace undotbs1 retention noguarantee;
总的来说,我们去查看undo表空间大小的时候,可以结合dba_data_files查看表空间分配大小,结合dba_undo_extents查看使用大小(包括expired和unexpired)
二v$sysstat和v$rollnamev$rollstat,v$undostat可去查看undo的统计信息,dba_rollback_segs和v$transaction可以查看undo的使用信息,并且通过v$transaction结合v$session还可以查找到对应使用回滚段的回话的sid。
当回滚表空间爆满处理:
一般来说,我们可以做如下处理:
1、添加undo表空间数据文件,这是要仔细研究过的,除非是你的undo表空间创建的时候真的设置太小,无法满足需求,才增加数据文件。
2、切换undo表空间,这是采用做多的做法,一般情况下,只有表空间使用非常大,消耗太多的磁盘空间。
------替换表空间:
遵循步骤:1、新建表空间----2、修改参数文件默认undo信息------3、查看回滚段的 使用情况(只用没有回话使用undo时才能删除。结合dba_rollback_segs或者v$rollstat查看)---offline原undo表空间---drop表空间
当回滚段损坏的处理:
一般情况下,一旦undo损坏,数据库就无法正常打开,模拟该环境,物理上删除undo数据文件:
SQL> startup
ORACLE instance started.
Total System Global Area 218103808 bytes
Fixed Size 1266680 bytes
Variable Size 79694856 bytes
Database Buffers 134217728 bytes
Redo Buffers 2924544 bytes
Database mounted.
ORA-01157: cannot identify/lock data file 2 - see DBWR trace file
ORA-01110: data file 2: '/oracle/app/oradata/orcl/undotbs1.dbf'
数据库启动报错,
此时我们可以将数据库的回滚段管理改成手动,AUTO---MANL并将回滚表空间改成系统回滚段来启动数据库。
SQL> create pfile='/oracle/initorcl.ora' from spfile;
File created.
修改参数文件:
#*.undo_tablespace='UNDOTBS1'
#*.undo_management='AUTO'
undo_management='MANUAL'
rollback_segments='SYSTEM'
修改完启动到mount阶段,offline并删除损坏undo数据文件,打开数据库。
SQL> startup mount pfile='/oracle/initorcl.ora';
SQL> alter database datafile '/oracle/app/oradata/orcl/undotbs1.dbf' offline drop;
SQL> alter database open;
删除原来的undo表空间,创建新的undo表空间。
SQL> drop tablespace undotbs1 including contents and datafiles
Tablespace dropped.
SQL> create undo tablespace undotbs1 datafile '/oracle/app/oradata/orcl/undotbs1.dbf' size 50m autoextend on;
Tablespace created.
重新将参数文件参数改回,启动数据库。
SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBASQN,UBAREC from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
22 12 66 10 175 98 28
表示回滚段号为22,事务槽为12
从v$rollstat中也可以看到对应的回滚段信息,XACTS是代表活动的事务。
SQL> select usn,writes,rssize,xacts,hwmsize,shrinks,wraps from v$rollstat;
USN WRITES RSSIZE XACTS HWMSIZE SHRINKS WRAPS
---------- ---------- ---------- ---------- ---------- ---------- ----------
0 7620 385024 0 385024 0 1
21 267816 2088960 0 2088960 0 0
22 36122 253952 1 253952 0 0
v$rollname视图可以用来获得回滚段名称。
SQL> select * from v$rollname where usn=22;
USN NAME
---------- ------------------------------
22 _SYSSMU22$
dump回滚段段头信息:
SQL> alter system dump undo header '_SYSSMU22$';
System altered.
SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name;
/oracle/app/admin/orcl/udump/orcl_ora_5949.trc
对于dump出来的文件:
Unix process pid: 5949, image: oracle@linux-4.7 (TNS V1-V3)
*** 2011-11-01 21:52:05.679
*** ACTION NAME:() 2011-11-01 21:52:05.666
*** MODULE NAME:(sqlplus@linux-4.7 (TNS V1-V3)) 2011-11-01 21:52:05.666
*** SERVICE NAME:(SYS$USERS) 2011-11-01 21:52:05.666
*** SESSION ID:(159.10) 2011-11-01 21:52:05.666
********************************************************************************
Undo Segment: _SYSSMU22$ (22)
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x00 9 0x00 0x0042 0x0001 0x0000.000c4af7 0x028000af 0x0000.000.00000000 0x00000001 0x00000000 1320152385
0x01 9 0x00 0x0042 0x0006 0x0000.000c4b1a 0x028000af 0x0000.000.00000000 0x00000001 0x00000000 1320152431
0x02 9 0x00 0x0041 0x0005 0x0000.000c4581 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
0x03 9 0x00 0x0041 0x000a 0x0000.000c44eb 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
0x04 9 0x00 0x0042 0x002e 0x0000.000c4a7c 0x028000af 0x0000.000.00000000 0x00000001 0x00000000 1320152138
0x05 9 0x00 0x0041 0x0012 0x0000.000c458b 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
0x06 9 0x00 0x0042 0x002b 0x0000.000c4b38 0x028000af 0x0000.000.00000000 0x00000001 0x00000000 1320152432
0x07 9 0x00 0x0041 0x001a 0x0000.000c464d 0x028000ad 0x0000.000.00000000 0x00000001 0x00000000 1320149924
0x08 9 0x00 0x0041 0x0023 0x0000.000c47e2 0x028000ad 0x0000.000.00000000 0x00000001 0x00000000 1320150762
0x09 9 0x00 0x0041 0x0014 0x0000.000c45b0 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
0x0a 9 0x00 0x0041 0x000b 0x0000.000c44ff 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
0x0b 9 0x00 0x0041 0x000e 0x0000.000c4513 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
0x0c 10 0x80 0x0042 0x0002 0x0000.00000000 0x028000af 0x0000.000.00000000 0x00000001 0x00000000 0
0x0d 9 0x00 0x0041 0x0008 0x0000.000c47ae 0x028000ad 0x0000.000.00000000 0x00000001 0x00000000 1320150644
0x0e 9 0x00 0x0041 0x000f 0x0000.000c4527 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
0x0f 9 0x00 0x0041 0x0010 0x0000.000c453b 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
0x10 9 0x00 0x0041 0x0013 0x0000.000c454e 0x028000ac 0x0000.000.00000000 0x00000001 0x00000000 1320149738
首先0x0c代表16进制,转换为2进制就是12,代表其占用第12个事务槽。stat为状态,9为非活动事务,10为活动事务。
dba即为data block address 指的是包含这个事务的前镜像的数据块地址0x028000af 将该地址做2进制转换即为0000 0010 1000 0000 0000 0000 1010 1111
前10位0000 0010 10运算代表所处的文件地址,后22位代表块地址运算得数值175,即该前镜像信息位于10号文件的175号块上.
这与事务中查询结果一致。
现在我们模拟另外一个回滚段事务的流程:
commit之前的事务,重新修改多条记录:
select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4000 30
7782 CLARK MANAGER 7839 09-JUN-81 4000 10
7788 SCOTT ANALYST 7566 19-APR-87 4000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 20
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 3000
SQL> update emp set sal=2000 where empno=7934;
SQL> update emp set sal=2000 where empno=7902;
SQL> update emp set sal=2000 where empno=7900;
SQL> update emp set sal=2000 where empno=7876;
SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBASQN,UBAREC from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
23 8 65 10 901 67 39
我们dump出回滚段中对应的10号文件的901号块:
SQL> alter system dump datafile 10 block 901;
SQL> oradebug setmypid;
SQL> oradebug tracefile_name;
/oracle/app/admin/orcl/udump/orcl_ora_6091.trc
查看信息:
UNDO BLK:
xid: 0x0017.008.00000041 seq: 0x43 cnt: 0x27 irb: 0x27 icl: 0x0 flg: 0x000
0
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f3c 0x02 0x1ed0 0x03 0x1e64 0x04 0x1de8 0x05 0x1d7c
0x06 0x1d10 0x07 0x1ca4 0x08 0x1bf8 0x09 0x1b8c 0x0a 0x1b08
0x0b 0x1aa8 0x0c 0x1a10 0x0d 0x198c 0x0e 0x1910 0x0f 0x183c
0x10 0x17b8 0x11 0x1734 0x12 0x1698 0x13 0x1644 0x14 0x15c0
0x15 0x1538 0x16 0x14b4 0x17 0x1460 0x18 0x13c4 0x19 0x1340
0x1a 0x12c4 0x1b 0x1240 0x1c 0x11b4 0x1d 0x1108 0x1e 0x1060
0x1f 0x0fac 0x20 0x0f60 0x21 0x0e7c 0x22 0x0e14 0x23 0x0dbc
0x24 0x0d24 0x25 0x0ccc 0x26 0x0c70 0x27 0x0c18
其中irb字段指的是回滚段中记录的最近的未提交变更开始出:
irb: 0x27
我们也可以发现,最后一个偏移地址正好是0x27 的信息。
找到0x27的信息:
* Rec #0x27 slt: 0x08 objn: 52173(0x0000cbcd) objd: 52173 tblspc: 4(0x000000
04)
* Layer: 11 (Row) opc: 1 rci 0x26
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
op: C uba: 0x02800385.0043.26
KDO Op code: URP row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x010000fc hdba: 0x010000fb
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 10(0xa) flag: 0x2c lock: 0 ckix: 191
ncol: 8 nnew: 1 size: 0
Vector content:
col 5: [ 2] c2 0c
对于c2 0c 转换为10进制为1100,即为我最后一个修改的数据的前镜像。
而rci则是代表了之后的一个偏移量。(同一事务中)
* Rec #0x26 slt: 0x08 objn: 52173(0x0000cbcd) objd: 52173 tblspc: 4(0x000000
04)
* Layer: 11 (Row) opc: 1 rci 0x25
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
op: C uba: 0x02800385.0043.25
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x010000fc hdba: 0x010000fb
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 11(0xb) flag: 0x2c lock: 0 ckix: 191
ncol: 8 nnew: 1 size: 1
col 5: [ 3] c2 0a 33
同样c2 0a 33 代表了10进制中的950;也就是倒数第二条更新的记录的前镜像。
依次跳转直到最后一undo chain 的rci为0x00
当有其他用户来读数据的时候,oracle会构造一致性读,通过前镜像把变化前的数据读取给用户。
看完上述内容,你们对undo表空间该怎么理解有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流