undo
============================
undo tablespace (9.2版本中推出)
rollback segment (8i之前)
===========================
创建undo表空间
C:\>sqlplus / as sysdba
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 7月 4 10:29:59 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> create undo tablespace undotbs2 datafile 'C:\ORADATA\ORCL\undotbs02.dbf' size 10m;
表空间已创建。
undo表空间只能保存undo段 ,undo段是系统自动创建的,每个undo段最少有2个extents
SQL> select owner,segment_name, segment_type,tablespace_name,extents from dba_Segments where tablespace_name='UNDOTBS2';
OWNER SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENTS
---------- ------------------- ------------------ --------------------------
SYS _SYSSMU11$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU12$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU13$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU14$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU15$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU16$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU17$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU18$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU19$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU20$ TYPE2 UNDO UNDOTBS2 2
10 rows selected
查看当前实例有多少undo段
select * from dba_rollback_segs
system表空间里也有一个undo段 ,注意 owner字段 (sys 表示只能为本实例用 ,public可以为集群环境的另一实例使用)
查看当前使用哪个undo表空间
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ----------------------------
undo_management string AUTO // 控制undo为自动或手动,从9i以后默认为自动
undo_retention integer 900
undo_tablespace string UNDOTBS1 // 当前使用哪个undo表空间
SQL>
如何修改实例的undo表空间
SQL> alter system set undo_tablespace=UNDOTBS2;
系统已更改。
SQL>
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS2
实验如下
创建一个 t表
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 b 30 2000
=====================================================
在session 1 中
SQL> select distinct sid from v$mystat;
SID
----------
147
SQL> update t set name='abc' where age=30;
已更新 1 行。
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 abc 30 2000
SQL>
在session 2 中
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 b 30 2000
SQL>
分析一下 数据是怎么读出来的
在session 1 中
SQL> select t.*,rowid from t;
ID NAME AGE SALARY ROWID
---------- ---------- ---------- ---------- ------------------
10 c 20 1000 AAAM6qAABAAAO9KAAA
20 abc 30 2000 AAAM6qAABAAAO9KAAB
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,dbms_rowid.rowid_block_number(rowid) blo from t;
FNO BLO
---------- ----------
1 61258
1 61258
可以看到表上的数据位于第1个文件的第 61258 个块上 ,然后从内存中dump出数据
SQL> alter system dump datafile 1 block 61258; // 从内存中dump出数据
系统已更改。
SQL>
SQL> show parameter user;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
license_max_users integer 0
parallel_adaptive_multi_user boolean TRUE
user_dump_dest string C:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP
以下是从内存中dump出来的具体日志
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dump file c:\oracle\product\10.2.0\admin\orcl\udump\orcl_ora_3224.trc
Wed Jul 04 11:38:30 2012
ORACLE V10.2.0.1.0 - Production vsnsta=0
vsnsql=14 vsnxtr=3
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Windows Server 2003 Version V5.2 Service Pack 2
CPU : 1 - type 586, 1 Physical Cores
Process Affinity : 0x00000000
Memory (Avail/Total): Ph:118M/511M, Ph+PgF:703M/1254M, VA:1610M/2047M
Instance name: orcl
Redo thread mounted by this instance: 1
Oracle process number: 27
Windows thread id: 3224, image: ORACLE.EXE (SHAD)
*** 2012-07-04 11:38:30.234
*** SERVICE NAME:(SYS$USERS) 2012-07-04 11:38:30.218
*** SESSION ID:(147.103) 2012-07-04 11:38:30.218
Start dump data blocks tsn: 0 file#: 1 minblk 61258 maxblk 61258
buffer tsn: 0 rdba: 0x0040ef4a (1/61258)
scn: 0x0000.001dcde9 seq: 0x01 flg: 0x04 tail: 0xcde90601
frmt: 0x02 chkval: 0xe540 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x0B4E7000 to 0x0B4E9000
B4E7000 0000A206 0040EF4A 001DCDE9 04010000 [....J.@.........]
B4E7010 0000E540 00290001 0000CEAA 001DCDE9 [@.....).........]
B4E7020 1FE80000 00031F02 00000000 000B000B [................]
B4E7030 00000004 01C0000B 001D0001 00008000 [................]
B4E7040 001DC7C3 00050013 00000005 01C0008F [................]
B4E7050 003B0001 00000001 00000000 00020100 [..;.............]
B4E7060 0016FFFF 1F6C1F74 00001F6C 1F920002 [....t.l.l.......]
B4E7070 00001F74 04A90004 042F1F5A 0000044E [t.......Z./.N...]
B4E7080 00000000 00000000 00000000 00000000 [................]
Repeat 64 times
..............................................................
...............................................................
..............................................................
...............................................................
..............................................................
...............................................................
B4E8FD0 0204022C 61033032 C1026362 15C2021F [,...20.abc......]
B4E8FE0 0204002C 62013032 021FC102 002C15C2 [,...20.b......,.]
B4E8FF0 30310204 C1026301 0BC20215 CDE90601 [..10.c..........]
Block header dump: 0x0040ef4a
Object id on Block? Y
seg/obj: 0xceaa csc: 0x00.1dcde9 itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000b.00b.00000004 0x01c0000b.0001.1d C--- 0 scn 0x0000.001dc7c3
0x02 0x0013.005.00000005 0x01c0008f.0001.3b ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0xb4e705c
===============
tsiz: 0x1fa0
hsiz: 0x16
pbl: 0x0b4e705c
bdba: 0x0040ef4a
76543210
flag=--------
ntab=1
nrow=2 //表示存了2条数据
frre=-1
fsbo=0x16
fseo=0x1f74
avsp=0x1f6c
tosp=0x1f6c
0xe:pti[0] nrow=2 ffs=0
0x12:pri[0] ffs=0x1f92
0x14:pri[1] ffs=0x1f74
block_row_dump:
tab 0, row 0, @0x1f92
tl: 14 fb: --H-FL-- lb: 0x0 cc: 4
col 0: [ 2] 31 30
col 1: [ 1] 63
col 2: [ 2] c1 15
col 3: [ 2] c2 0b
tab 0, row 1, @0x1f74
tl: 16 fb: --H-FL-- lb: 0x2 cc: 4
col 0: [ 2] 32 30
col 1: [ 3] 61 62 63
col 2: [ 2] c1 1f
col 3: [ 2] c2 15
end_of_block_dump
End dump data blocks tsn: 0 file#: 1 minblk 61258 maxblk 61258
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
下面来具体分析一下:
SQL> update t set name='abc' where age=30;
已更新 1 行。
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 abc 30 2000
因为我们修改的是第2行数据的第2列,即: name列的数值,因此将第2行数据单独拿出来
tab 0, row 1, @0x1f74
tl: 16 fb: --H-FL-- lb: 0x2 cc: 4
col 0: [ 2] 32 30
col 1: [ 3] 61 62 63 // 重点关注这一行
col 2: [ 2] c1 1f
col 3: [ 2] c2 15
查看a、b、c的 ascii
SQL> select ascii('a') from dual;
ASCII('A')
----------
97
SQL> select ascii('b') from dual;
ASCII('B')
----------
98
SQL> select ascii('c') from dual;
ASCII('C')
----------
99
ascii区分大小写
c的ascii码为99 ,它是十进制数,转换为16进制数,刚好为63
从磁盘上dump出数据文件的内容
1号数据文件的绝对路径为 'C:\ORADATA\ORCL\SYSTEM01.DBF'
alter system dump datafile 'C:\ORADATA\ORCL\SYSTEM01.DBF' block 61258;
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*** 2012-07-04 13:43:42.812
Start dump data block from file C:\ORADATA\ORCL\SYSTEM01.DBF minblk 61258 maxblk 61258
V10 STYLE. FILE HEADER:
Compatibility Vsn = 169869568=0xa200100
Db ID=1307921831=0x4df54da7, Db Name='ORCL'
Activation ID=0=0x0
Control Seq=1789=0x6fd, File size=62720=0xf500
File Number=1, Blksiz=8192, File Type=3 DATA
Dump all the blocks in range:
buffer tsn: 0 rdba: 0x0040ef4a (1/61258)
scn: 0x0000.001dcde9 seq: 0x01 flg: 0x04 tail: 0xcde90601
frmt: 0x02 chkval: 0xe540 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x0B4E7000 to 0x0B4E9000
B4E7000 0000A206 0040EF4A 001DCDE9 04010000 [....J.@.........]
B4E7010 0000E540 00290001 0000CEAA 001DCDE9 [@.....).........]
B4E7020 1FE80000 00031F02 00000000 000B000B [................]
B4E7030 00000004 01C0000B 001D0001 00008000 [................]
B4E7040 001DC7C3 00050013 00000005 01C0008F [................]
B4E7050 003B0001 00000001 00000000 00020100 [..;.............]
B4E7060 0016FFFF 1F6C1F74 00001F6C 1F920002 [....t.l.l.......]
B4E7070 00001F74 04A90004 042F1F5A 0000044E [t.......Z./.N...]
B4E7080 00000000 00000000 00000000 00000000 [................]
Repeat 64 times
B4E7490 2C000000 C8100300 7938D594 473BFA3F [...,......8y?.;G]
.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
B4E8FF0 30310204 C1026301 0BC20215 CDE90601 [..10.c..........]
Block header dump: 0x0040ef4a
Object id on Block? Y
seg/obj: 0xceaa csc: 0x00.1dcde9 itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000b.00b.00000004 0x01c0000b.0001.1d C--- 0 scn 0x0000.001dc7c3
0x02 0x0013.005.00000005 0x01c0008f.0001.3b ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0xb4e705c
===============
tsiz: 0x1fa0
hsiz: 0x16
pbl: 0x0b4e705c
bdba: 0x0040ef4a
76543210
flag=--------
ntab=1
nrow=2 //数据的行数
frre=-1
fsbo=0x16
fseo=0x1f74
avsp=0x1f6c
tosp=0x1f6c
0xe:pti[0] nrow=2 offs=0
0x12:pri[0] offs=0x1f92
0x14:pri[1] offs=0x1f74
block_row_dump:
tab 0, row 0, @0x1f92
tl: 14 fb: --H-FL-- lb: 0x0 cc: 4
col 0: [ 2] 31 30
col 1: [ 1] 63
col 2: [ 2] c1 15
col 3: [ 2] c2 0b
tab 0, row 1, @0x1f74
tl: 16 fb: --H-FL-- lb: 0x2 cc: 4
col 0: [ 2] 32 30
col 1: [ 3] 61 62 63
col 2: [ 2] c1 1f
col 3: [ 2] c2 15
end_of_block_dump
End dump data block from file C:\ORADATA\ORCL\SYSTEM01.DBF minblk 61258 maxblk 61258
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
其中 lb: 0x2 表示这行数据被锁定了,没有锁定是 lb: 0x0
到底锁定的是哪行数据,从下面的信息中可以看到
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000b.00b.00000004 0x01c0000b.0001.1d C--- 0 scn 0x0000.001dc7c3
0x02 0x0013.005.00000005 0x01c0008f.0001.3b ---- 1 fsc 0x0000.00000000
任何事务想修改块上的数据,必须先获得一个 Itl , 而 Flag中 ‘----’表示有1个事务正修改数据块 , Lck 中的 ‘1’ 表示 当前锁定的数据为1条
uba是 undo block address: 0x01c0008f.0001.3b
从 v$transaction 视图中可以看到 之前update的事务还没有提交,但是修改却写到到了磁盘的数据文件上了。
有时候即使做了commit的事务,还是没有写到数据文件中,commit操作之能保证日志写到日志文件中。
那么什么时候内存中的数据会写到数据文件中呢?see 下 dbwr满足的条件。
那么事务没有结束,那么session 2中的内容又是从哪里读到的呢?-----undo中
SQL> select distinct sid from v$mystat;
SID
----------
151
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 b 30 2000
uba是 undo block address:0x01c0008f.0001.3b,它是16进制数
先转换为10进制数
SQL> select to_number('01c0008f','xxxxxxxx') from dual;
TO_NUMBER('01C0008F','XXXXXXXX')
--------------------------------
29360271
然后利用oracle的工具包,找到数据所在的文件编号和块编号
SQL> select dbms_utility.data_block_address_file(29360271) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(29360271)
----------------------------------------------
7
SQL>
SQL> select dbms_utility.data_block_address_block(29360271) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(29360271)
-----------------------------------------------
143
SQL>
7号数据文件刚好是undo表空间,也就是我们当前使用的undo表空间
SQL> select file_name,file_id,tablespace_name from dba_data_files where file_id=7;
FILE_NAME FILE_ID TABLESPACE_NAME
----------------------------------- ---------- ---------------
C:\ORADATA\ORCL\UNDOTBS02.DBF 7 UNDOTBS2
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS2
那么 UNDOTBS2有多少个回滚段呢 ?
select * from dba_rollback_segs where tablespace_name='UNDOTBS2' 可以看到有10个回滚段
那么当前事务到底使用了哪个回滚段呢?
v$rollstat 为每一个处于online的回滚段提供了一条记录,用来跟踪对回滚段的使用情况
select * from v$rollstat
字段XACTS 表示每个回滚段上具有的活动事务数量,如果为1 ,那么表示当前回滚段持有事务,USN表示 undo段的编号,它为19
select * from dba_rollback_segs where segment_id=19
找到 段名 (segment_name)为 _SYSSMU19$ ,然后可以跟踪到段所在的区 信息
SQL> select * from dba_extents where segment_name='_SYSSMU19$';
OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
-------- ---------------- ------------------- ------------------ ---------------- ---------- ---------- ---------- ---------- ---------- ------------
SYS _SYSSMU19$ TYPE2 UNDO UNDOTBS2 0 7 137 65536 8 7
SYS _SYSSMU19$ TYPE2 UNDO UNDOTBS2 1 7 145 65536 8 7
SQL>
可以看到一个段最少包含两个区(extents),从之前的算出来的 143 是属于 第1个extent 上
然后dump出内存中关于undo的信息
日志如下
*** 2012-07-04 14:48:14.078
*** SERVICE NAME:(SYS$USERS) 2012-07-04 14:48:14.078
*** SESSION ID:(151.1104) 2012-07-04 14:48:14.078
Start dump data blocks tsn: 5 file#: 7 minblk 143 maxblk 143
buffer tsn: 5 rdba: 0x01c0008f (7/143)
scn: 0x0000.001dcd25 seq: 0x01 flg: 0x04 tail: 0xcd250201
frmt: 0x02 chkval: 0xe318 type: 0x02=KTU UNDO BLOCK
Hex dump of block: st=0, typ_found=1
。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。
********************************************************************************
UNDO BLK:
xid: 0x0013.005.00000005 seq: 0x1 cnt: 0x3b irb: 0x3b icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f38 0x02 0x1ec8 0x03 0x1e88 0x04 0x1dec 0x05 0x1d3c
0x06 0x1cdc 0x07 0x1c0c 0x08 0x1b8c 0x09 0x1b0c 0x0a 0x1a74
0x0b 0x19f4 0x0c 0x1980 0x0d 0x1900 0x0e 0x188c 0x0f 0x17d8
0x10 0x1734 0x11 0x1690 0x12 0x1610 0x13 0x15b4 0x14 0x1510
0x15 0x146c 0x16 0x13c8 0x17 0x1304 0x18 0x1284 0x19 0x11cc
0x1a 0x1164 0x1b 0x110c 0x1c 0x10b4 0x1d 0x105c 0x1e 0x0fdc
0x1f 0x0f54 0x20 0x0ebc 0x21 0x0e3c 0x22 0x0dbc 0x23 0x0d28
0x24 0x0cb8 0x25 0x0c78 0x26 0x0bf8 0x27 0x0b64 0x28 0x0ae4
0x29 0x0a74 0x2a 0x09ec 0x2b 0x09ac 0x2c 0x092c 0x2d 0x08a8
0x2e 0x0850 0x2f 0x0810 0x30 0x0790 0x31 0x070c 0x32 0x06a0
0x33 0x0650 0x34 0x05b4 0x35 0x0500 0x36 0x048c 0x37 0x03d8
0x38 0x0340 0x39 0x02c0 0x3a 0x0248 0x3b 0x01c8
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
根据之前的 uba 信息 :0x01c0008f.0001.3b ,其中3b表示 事务的记录编号,
那么当前事务对应的事务编号记录为如下:其中 col 1: [ 1] 62 中62 就是 b
*-----------------------------
* Rec #0x3b slt: 0x05 objn: 52906(0x0000ceaa) objd: 52906 tblspc: 0(0x00000000)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x01c0008f.0001.39 ctl max scn: 0x0000.001dc6de prv tx scn: 0x0000.001dc6f2
txn start scn: scn: 0x0000.001dcba7 logon user: 0
prev brb: 29360267 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x0040ef4a hdba: 0x0040ef49
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 10
ncol: 4 nnew: 1 size: -2
col 1: [ 1] 62
像上面中以 Rec开头的为一个完整的记录
为了验证是否正确,可以从 v$transaction 视图中核对
SQL> select addr, xidusn, xidslot, xid ,ubafil ,ubablk ,ubasqn ,ubarec,status from v$transaction ;
ADDR XIDUSN XIDSLOT XID UBAFIL UBABLK UBASQN UBAREC STATUS
-------- ---------- ---------- ---------------- ---------- ---------- ---------- ---------- ----------------
1D630CF4 19 5 1300050005000000 7 143 1 59 ACTIVE
其中uba: 0x01c0008f.0001.3b 信息里面的 0x01c0008f 跟 v$transaction 中的 UBAFIL(文件编号)、UBABLK (块编号)对应,
0001 对应于 v$transaction 中的UBASQN , 3b对应于 v$transaction 中的 UBAREC
============================
undo tablespace (9.2版本中推出)
rollback segment (8i之前)
===========================
创建undo表空间
C:\>sqlplus / as sysdba
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 7月 4 10:29:59 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> create undo tablespace undotbs2 datafile 'C:\ORADATA\ORCL\undotbs02.dbf' size 10m;
表空间已创建。
undo表空间只能保存undo段 ,undo段是系统自动创建的,每个undo段最少有2个extents
SQL> select owner,segment_name, segment_type,tablespace_name,extents from dba_Segments where tablespace_name='UNDOTBS2';
OWNER SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENTS
---------- ------------------- ------------------ --------------------------
SYS _SYSSMU11$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU12$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU13$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU14$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU15$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU16$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU17$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU18$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU19$ TYPE2 UNDO UNDOTBS2 2
SYS _SYSSMU20$ TYPE2 UNDO UNDOTBS2 2
10 rows selected
查看当前实例有多少undo段
select * from dba_rollback_segs
system表空间里也有一个undo段 ,注意 owner字段 (sys 表示只能为本实例用 ,public可以为集群环境的另一实例使用)
查看当前使用哪个undo表空间
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ----------------------------
undo_management string AUTO // 控制undo为自动或手动,从9i以后默认为自动
undo_retention integer 900
undo_tablespace string UNDOTBS1 // 当前使用哪个undo表空间
SQL>
如何修改实例的undo表空间
SQL> alter system set undo_tablespace=UNDOTBS2;
系统已更改。
SQL>
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS2
实验如下
创建一个 t表
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 b 30 2000
=====================================================
在session 1 中
SQL> select distinct sid from v$mystat;
SID
----------
147
SQL> update t set name='abc' where age=30;
已更新 1 行。
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 abc 30 2000
SQL>
在session 2 中
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 b 30 2000
SQL>
分析一下 数据是怎么读出来的
在session 1 中
SQL> select t.*,rowid from t;
ID NAME AGE SALARY ROWID
---------- ---------- ---------- ---------- ------------------
10 c 20 1000 AAAM6qAABAAAO9KAAA
20 abc 30 2000 AAAM6qAABAAAO9KAAB
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,dbms_rowid.rowid_block_number(rowid) blo from t;
FNO BLO
---------- ----------
1 61258
1 61258
可以看到表上的数据位于第1个文件的第 61258 个块上 ,然后从内存中dump出数据
SQL> alter system dump datafile 1 block 61258; // 从内存中dump出数据
系统已更改。
SQL>
SQL> show parameter user;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
license_max_users integer 0
parallel_adaptive_multi_user boolean TRUE
user_dump_dest string C:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP
以下是从内存中dump出来的具体日志
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dump file c:\oracle\product\10.2.0\admin\orcl\udump\orcl_ora_3224.trc
Wed Jul 04 11:38:30 2012
ORACLE V10.2.0.1.0 - Production vsnsta=0
vsnsql=14 vsnxtr=3
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Windows Server 2003 Version V5.2 Service Pack 2
CPU : 1 - type 586, 1 Physical Cores
Process Affinity : 0x00000000
Memory (Avail/Total): Ph:118M/511M, Ph+PgF:703M/1254M, VA:1610M/2047M
Instance name: orcl
Redo thread mounted by this instance: 1
Oracle process number: 27
Windows thread id: 3224, image: ORACLE.EXE (SHAD)
*** 2012-07-04 11:38:30.234
*** SERVICE NAME:(SYS$USERS) 2012-07-04 11:38:30.218
*** SESSION ID:(147.103) 2012-07-04 11:38:30.218
Start dump data blocks tsn: 0 file#: 1 minblk 61258 maxblk 61258
buffer tsn: 0 rdba: 0x0040ef4a (1/61258)
scn: 0x0000.001dcde9 seq: 0x01 flg: 0x04 tail: 0xcde90601
frmt: 0x02 chkval: 0xe540 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x0B4E7000 to 0x0B4E9000
B4E7000 0000A206 0040EF4A 001DCDE9 04010000 [....J.@.........]
B4E7010 0000E540 00290001 0000CEAA 001DCDE9 [@.....).........]
B4E7020 1FE80000 00031F02 00000000 000B000B [................]
B4E7030 00000004 01C0000B 001D0001 00008000 [................]
B4E7040 001DC7C3 00050013 00000005 01C0008F [................]
B4E7050 003B0001 00000001 00000000 00020100 [..;.............]
B4E7060 0016FFFF 1F6C1F74 00001F6C 1F920002 [....t.l.l.......]
B4E7070 00001F74 04A90004 042F1F5A 0000044E [t.......Z./.N...]
B4E7080 00000000 00000000 00000000 00000000 [................]
Repeat 64 times
..............................................................
...............................................................
..............................................................
...............................................................
..............................................................
...............................................................
B4E8FD0 0204022C 61033032 C1026362 15C2021F [,...20.abc......]
B4E8FE0 0204002C 62013032 021FC102 002C15C2 [,...20.b......,.]
B4E8FF0 30310204 C1026301 0BC20215 CDE90601 [..10.c..........]
Block header dump: 0x0040ef4a
Object id on Block? Y
seg/obj: 0xceaa csc: 0x00.1dcde9 itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000b.00b.00000004 0x01c0000b.0001.1d C--- 0 scn 0x0000.001dc7c3
0x02 0x0013.005.00000005 0x01c0008f.0001.3b ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0xb4e705c
===============
tsiz: 0x1fa0
hsiz: 0x16
pbl: 0x0b4e705c
bdba: 0x0040ef4a
76543210
flag=--------
ntab=1
nrow=2 //表示存了2条数据
frre=-1
fsbo=0x16
fseo=0x1f74
avsp=0x1f6c
tosp=0x1f6c
0xe:pti[0] nrow=2 ffs=0
0x12:pri[0] ffs=0x1f92
0x14:pri[1] ffs=0x1f74
block_row_dump:
tab 0, row 0, @0x1f92
tl: 14 fb: --H-FL-- lb: 0x0 cc: 4
col 0: [ 2] 31 30
col 1: [ 1] 63
col 2: [ 2] c1 15
col 3: [ 2] c2 0b
tab 0, row 1, @0x1f74
tl: 16 fb: --H-FL-- lb: 0x2 cc: 4
col 0: [ 2] 32 30
col 1: [ 3] 61 62 63
col 2: [ 2] c1 1f
col 3: [ 2] c2 15
end_of_block_dump
End dump data blocks tsn: 0 file#: 1 minblk 61258 maxblk 61258
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
下面来具体分析一下:
SQL> update t set name='abc' where age=30;
已更新 1 行。
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 abc 30 2000
因为我们修改的是第2行数据的第2列,即: name列的数值,因此将第2行数据单独拿出来
tab 0, row 1, @0x1f74
tl: 16 fb: --H-FL-- lb: 0x2 cc: 4
col 0: [ 2] 32 30
col 1: [ 3] 61 62 63 // 重点关注这一行
col 2: [ 2] c1 1f
col 3: [ 2] c2 15
查看a、b、c的 ascii
SQL> select ascii('a') from dual;
ASCII('A')
----------
97
SQL> select ascii('b') from dual;
ASCII('B')
----------
98
SQL> select ascii('c') from dual;
ASCII('C')
----------
99
ascii区分大小写
c的ascii码为99 ,它是十进制数,转换为16进制数,刚好为63
从磁盘上dump出数据文件的内容
1号数据文件的绝对路径为 'C:\ORADATA\ORCL\SYSTEM01.DBF'
alter system dump datafile 'C:\ORADATA\ORCL\SYSTEM01.DBF' block 61258;
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*** 2012-07-04 13:43:42.812
Start dump data block from file C:\ORADATA\ORCL\SYSTEM01.DBF minblk 61258 maxblk 61258
V10 STYLE. FILE HEADER:
Compatibility Vsn = 169869568=0xa200100
Db ID=1307921831=0x4df54da7, Db Name='ORCL'
Activation ID=0=0x0
Control Seq=1789=0x6fd, File size=62720=0xf500
File Number=1, Blksiz=8192, File Type=3 DATA
Dump all the blocks in range:
buffer tsn: 0 rdba: 0x0040ef4a (1/61258)
scn: 0x0000.001dcde9 seq: 0x01 flg: 0x04 tail: 0xcde90601
frmt: 0x02 chkval: 0xe540 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x0B4E7000 to 0x0B4E9000
B4E7000 0000A206 0040EF4A 001DCDE9 04010000 [....J.@.........]
B4E7010 0000E540 00290001 0000CEAA 001DCDE9 [@.....).........]
B4E7020 1FE80000 00031F02 00000000 000B000B [................]
B4E7030 00000004 01C0000B 001D0001 00008000 [................]
B4E7040 001DC7C3 00050013 00000005 01C0008F [................]
B4E7050 003B0001 00000001 00000000 00020100 [..;.............]
B4E7060 0016FFFF 1F6C1F74 00001F6C 1F920002 [....t.l.l.......]
B4E7070 00001F74 04A90004 042F1F5A 0000044E [t.......Z./.N...]
B4E7080 00000000 00000000 00000000 00000000 [................]
Repeat 64 times
B4E7490 2C000000 C8100300 7938D594 473BFA3F [...,......8y?.;G]
.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
B4E8FF0 30310204 C1026301 0BC20215 CDE90601 [..10.c..........]
Block header dump: 0x0040ef4a
Object id on Block? Y
seg/obj: 0xceaa csc: 0x00.1dcde9 itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000b.00b.00000004 0x01c0000b.0001.1d C--- 0 scn 0x0000.001dc7c3
0x02 0x0013.005.00000005 0x01c0008f.0001.3b ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0xb4e705c
===============
tsiz: 0x1fa0
hsiz: 0x16
pbl: 0x0b4e705c
bdba: 0x0040ef4a
76543210
flag=--------
ntab=1
nrow=2 //数据的行数
frre=-1
fsbo=0x16
fseo=0x1f74
avsp=0x1f6c
tosp=0x1f6c
0xe:pti[0] nrow=2 offs=0
0x12:pri[0] offs=0x1f92
0x14:pri[1] offs=0x1f74
block_row_dump:
tab 0, row 0, @0x1f92
tl: 14 fb: --H-FL-- lb: 0x0 cc: 4
col 0: [ 2] 31 30
col 1: [ 1] 63
col 2: [ 2] c1 15
col 3: [ 2] c2 0b
tab 0, row 1, @0x1f74
tl: 16 fb: --H-FL-- lb: 0x2 cc: 4
col 0: [ 2] 32 30
col 1: [ 3] 61 62 63
col 2: [ 2] c1 1f
col 3: [ 2] c2 15
end_of_block_dump
End dump data block from file C:\ORADATA\ORCL\SYSTEM01.DBF minblk 61258 maxblk 61258
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
其中 lb: 0x2 表示这行数据被锁定了,没有锁定是 lb: 0x0
到底锁定的是哪行数据,从下面的信息中可以看到
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000b.00b.00000004 0x01c0000b.0001.1d C--- 0 scn 0x0000.001dc7c3
0x02 0x0013.005.00000005 0x01c0008f.0001.3b ---- 1 fsc 0x0000.00000000
任何事务想修改块上的数据,必须先获得一个 Itl , 而 Flag中 ‘----’表示有1个事务正修改数据块 , Lck 中的 ‘1’ 表示 当前锁定的数据为1条
uba是 undo block address: 0x01c0008f.0001.3b
从 v$transaction 视图中可以看到 之前update的事务还没有提交,但是修改却写到到了磁盘的数据文件上了。
有时候即使做了commit的事务,还是没有写到数据文件中,commit操作之能保证日志写到日志文件中。
那么什么时候内存中的数据会写到数据文件中呢?see 下 dbwr满足的条件。
那么事务没有结束,那么session 2中的内容又是从哪里读到的呢?-----undo中
SQL> select distinct sid from v$mystat;
SID
----------
151
SQL> select * from t;
ID NAME AGE SALARY
---------- ---------- ---------- ----------
10 c 20 1000
20 b 30 2000
uba是 undo block address:0x01c0008f.0001.3b,它是16进制数
先转换为10进制数
SQL> select to_number('01c0008f','xxxxxxxx') from dual;
TO_NUMBER('01C0008F','XXXXXXXX')
--------------------------------
29360271
然后利用oracle的工具包,找到数据所在的文件编号和块编号
SQL> select dbms_utility.data_block_address_file(29360271) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(29360271)
----------------------------------------------
7
SQL>
SQL> select dbms_utility.data_block_address_block(29360271) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(29360271)
-----------------------------------------------
143
SQL>
7号数据文件刚好是undo表空间,也就是我们当前使用的undo表空间
SQL> select file_name,file_id,tablespace_name from dba_data_files where file_id=7;
FILE_NAME FILE_ID TABLESPACE_NAME
----------------------------------- ---------- ---------------
C:\ORADATA\ORCL\UNDOTBS02.DBF 7 UNDOTBS2
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS2
那么 UNDOTBS2有多少个回滚段呢 ?
select * from dba_rollback_segs where tablespace_name='UNDOTBS2' 可以看到有10个回滚段
那么当前事务到底使用了哪个回滚段呢?
v$rollstat 为每一个处于online的回滚段提供了一条记录,用来跟踪对回滚段的使用情况
select * from v$rollstat
字段XACTS 表示每个回滚段上具有的活动事务数量,如果为1 ,那么表示当前回滚段持有事务,USN表示 undo段的编号,它为19
select * from dba_rollback_segs where segment_id=19
找到 段名 (segment_name)为 _SYSSMU19$ ,然后可以跟踪到段所在的区 信息
SQL> select * from dba_extents where segment_name='_SYSSMU19$';
OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
-------- ---------------- ------------------- ------------------ ---------------- ---------- ---------- ---------- ---------- ---------- ------------
SYS _SYSSMU19$ TYPE2 UNDO UNDOTBS2 0 7 137 65536 8 7
SYS _SYSSMU19$ TYPE2 UNDO UNDOTBS2 1 7 145 65536 8 7
SQL>
可以看到一个段最少包含两个区(extents),从之前的算出来的 143 是属于 第1个extent 上
然后dump出内存中关于undo的信息
日志如下
*** 2012-07-04 14:48:14.078
*** SERVICE NAME:(SYS$USERS) 2012-07-04 14:48:14.078
*** SESSION ID:(151.1104) 2012-07-04 14:48:14.078
Start dump data blocks tsn: 5 file#: 7 minblk 143 maxblk 143
buffer tsn: 5 rdba: 0x01c0008f (7/143)
scn: 0x0000.001dcd25 seq: 0x01 flg: 0x04 tail: 0xcd250201
frmt: 0x02 chkval: 0xe318 type: 0x02=KTU UNDO BLOCK
Hex dump of block: st=0, typ_found=1
。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。
********************************************************************************
UNDO BLK:
xid: 0x0013.005.00000005 seq: 0x1 cnt: 0x3b irb: 0x3b icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f38 0x02 0x1ec8 0x03 0x1e88 0x04 0x1dec 0x05 0x1d3c
0x06 0x1cdc 0x07 0x1c0c 0x08 0x1b8c 0x09 0x1b0c 0x0a 0x1a74
0x0b 0x19f4 0x0c 0x1980 0x0d 0x1900 0x0e 0x188c 0x0f 0x17d8
0x10 0x1734 0x11 0x1690 0x12 0x1610 0x13 0x15b4 0x14 0x1510
0x15 0x146c 0x16 0x13c8 0x17 0x1304 0x18 0x1284 0x19 0x11cc
0x1a 0x1164 0x1b 0x110c 0x1c 0x10b4 0x1d 0x105c 0x1e 0x0fdc
0x1f 0x0f54 0x20 0x0ebc 0x21 0x0e3c 0x22 0x0dbc 0x23 0x0d28
0x24 0x0cb8 0x25 0x0c78 0x26 0x0bf8 0x27 0x0b64 0x28 0x0ae4
0x29 0x0a74 0x2a 0x09ec 0x2b 0x09ac 0x2c 0x092c 0x2d 0x08a8
0x2e 0x0850 0x2f 0x0810 0x30 0x0790 0x31 0x070c 0x32 0x06a0
0x33 0x0650 0x34 0x05b4 0x35 0x0500 0x36 0x048c 0x37 0x03d8
0x38 0x0340 0x39 0x02c0 0x3a 0x0248 0x3b 0x01c8
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
根据之前的 uba 信息 :0x01c0008f.0001.3b ,其中3b表示 事务的记录编号,
那么当前事务对应的事务编号记录为如下:其中 col 1: [ 1] 62 中62 就是 b
*-----------------------------
* Rec #0x3b slt: 0x05 objn: 52906(0x0000ceaa) objd: 52906 tblspc: 0(0x00000000)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x01c0008f.0001.39 ctl max scn: 0x0000.001dc6de prv tx scn: 0x0000.001dc6f2
txn start scn: scn: 0x0000.001dcba7 logon user: 0
prev brb: 29360267 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x0040ef4a hdba: 0x0040ef49
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 10
ncol: 4 nnew: 1 size: -2
col 1: [ 1] 62
像上面中以 Rec开头的为一个完整的记录
为了验证是否正确,可以从 v$transaction 视图中核对
SQL> select addr, xidusn, xidslot, xid ,ubafil ,ubablk ,ubasqn ,ubarec,status from v$transaction ;
ADDR XIDUSN XIDSLOT XID UBAFIL UBABLK UBASQN UBAREC STATUS
-------- ---------- ---------- ---------------- ---------- ---------- ---------- ---------- ----------------
1D630CF4 19 5 1300050005000000 7 143 1 59 ACTIVE
其中uba: 0x01c0008f.0001.3b 信息里面的 0x01c0008f 跟 v$transaction 中的 UBAFIL(文件编号)、UBABLK (块编号)对应,
0001 对应于 v$transaction 中的UBASQN , 3b对应于 v$transaction 中的 UBAREC
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24862808/viewspace-734555/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/24862808/viewspace-734555/