oracle 体系结构及内存管理 12_undo

一、Undo表空间及管理方式:建立实例时自动建立,自动生成undo段(默认会自动生成11个undo段,一个系统undo段,10
个普通undo段),system回滚段,对数据字典操做时,如创建表,记录相关信息区是自动分配的,分配给段的区能够是
不连续的,区中的块是连续的,9i前段的区都是手动管理,比较麻烦。
查询undo表空间中已建立的undo段信息
    select * from v$rollname;
    select * from dba_rollback_segs;        
查询undo段的区块信息 dba_segments,dba_extents
    select SEGMENT_NAME,EXTENTS,BLOCKS from dba_segments where SEGMENT_NAME='_SYSSMU1$';
    select SEGMENT_NAME,TABLESPACE_NAME,EXTENT_ID,FILE_ID,BLOCK_ID,BLOCKS from dba_extents where SEGMENT_NAME='_SYSSMU1$';
    
二、undo advisor UNDO大小设置
    利用EM获取系统建议大小:最长sql语句执行时间,闪回考虑,undo大小设置要参考时间因素    
show parameter undo
    undo_management #UNOD的管理方式 AUTO
    undo_retention  #设置保留时间
        alter tablespace undotbs1 retention guarantee; #inactive状态的区继续保留不被覆盖
        alter tablespace undotbs1 retention noguarantee;  #尽可能保留
        select retention from dba_tablespaces; sql

三、undo的做用与undo区状态
undo的三个做用:主要缘由实现了存储修改前的数据
    读一致性,构造CR块:会话修改未提交的数据别的会话不能读,未修改的数据和undo中的数据构造CR块
    回滚:修改前的数据先存入undo表空间里的undo段里,方便回滚
    实例恢复:前滚,回滚
Undo段中区的状态
    free:未使用,未分配给任何段
    expired:过时,不会释放成free
    inactive:提交后,但愿继续还会保留(undo_retention)时间
    active:正在使用的事物未提交
查询UNDO区状态等信息 dba_undo_extents
    SELECT extent_id, bytes, status FROM dba_undo_extents WHERE segment_name='_SYSSMU1$';
    区的自动分配先用free空间,再扩展undo表空间,再使用expired,expired通常不会释放为free缓存

四、图解一个事务的操做流程
    事务表:回滚段段头块的结构,存储回滚段事务信息,最多能够存储47个事务信息;
        select header_block,header_file from dba_segments where segment_name='_SYSSMU1$';
    UBA:(Undo Block Address)回滚块地址;
    事务槽:ITL数据块头部结构,存储数据块的事务信息;
    事务ID:事务标识号;
        select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction;
事务操做流程:
    开始一个事务后,先找一个相对空闲的回滚段,在回滚段段头块的事务表里写入事务XID,同时在回滚段里分配空
的回滚块事务表中记录回滚块的UBA;在要修改的数据块的事务槽里写入事务XID和回滚块的UBA,同时记录事务提交标
识,开始修改数据行,在数据行上写事务XID,修改前数据写入回滚块。
    事务表里记录最新的回滚块UBA方便回滚,数据块记录回滚块UBA方便构造CR块,实现一致性读,数据块记录事务
XID方便找事务表里的XID实现快速提交。
    事务表里的事务提交标识最标准反映出事务是否已提交。提交时只更新事务表提交标识,数据块和数据行上的事
务信息不必定所有更新,当新的操做须要读取或者修改某行数据时,发现行上有事务XID,会去事务槽中核实,再去事
务表里核实,发现事务表的事务已提交,会更新事务槽和数据行事务信息,由于oracle全部改变过程都会记日志因此
select操做也可能会产生redo。
    事务过程全部的数据块修改过程均产生redo和undo,因此一个数据块,根据当前的undo数据能够一直向回找到足
够早的数据。session

五、读一致性与ORA-01555错误
    ORA-01555错误:向回构造CR读时,因空间不足以前的数据已经被覆盖,不能构造到开始读的状态数据。
    eg:8:40开始查询一个10万条数据的表,8:45一个事务删除了表的最后100行,提交了,8:50查询完成,那么查询
的结果是10万行,实现机制就是由于全部的数据块修改都作undo,根据undo往回找同一个事务状态下的数据。当找不
到足够早的数据时提示ORA-01555错误。主要由于查询时间太长和undo表空间压力过大    oracle

六、事务槽ITL
每个oracle数据块头都有事务槽,默认是1,能够改最大255(从Oracle10g开始不能更改)
    select INI_TRANS,MAX_TRANS from dba_tables where table_name='T2'
事务槽争用
    一个数据块要被修改,会在事务槽中记录XID(事务ID)和回滚块的UBA,多个事务修改同一个块时,由于未提
交的事务槽不能被覆盖,因此都会获取新的事务槽导致块的PCT_free往下压,同时修改的数据行增长行的大小空间往
上压,会导致预留pct_free空间不够,引发事务槽争用状况;
    当多个事务向同一张表中并行插入数据时oracle会自动使第一个事务操做第一个块,第二个事务操做第二个块,
以减小事务槽争用,可是对应update和delete时就无能为力了,因此事务槽争用主要发生在修改和删除操做上。        工具

七、DUMP工具
    alter system dump undo header '_SYSSMU1$'; #转储回滚段头
    alter system dump datafile 2 block 9;   #转储回滚段数据块
http://blog.itpub.net/28507395/viewspace-1328056spa

八、图解Oracle IMU机制,private redo strands机制
    在shared pool中对每一个事务分配IMU buffer用于记录回滚数据,同时对IMU buffer的改变在shared pool中分配
记录日志的空间redo private strands,日志直接有LGWn写入redo log,IMU buffer写满后转到buffer cache再写
入数据文件。缓存了回滚块,能快速的找到回滚块,构造CR时间缩短。
    select * from v$sysstat where name like '%IMU%';
    
九、undo相关查询
查看回滚段的使用状况,哪一个用户正在使用回滚段的资源
    select s.username, u.name from v$transaction t,v$rollstat r,v$rollname u,v$session s 
    where s.taddr=t.addr and t.xidusn=r.usn and r.usn=u.usn order by s.username;
检查UNDO Segment状态
    select usn,xacts,rssize/1024/1024/1024,hwmsize/1024/1024/1024,shrinks  from v$rollstat order by rssize;
查询UNDO表空间统计信息
    SELECT TO_CHAR(BEGIN_TIME,'HH24:MI:SS') BEGIN_TIME, TO_CHAR(END_TIME,'HH24:MI:SS') END_TIME,UNDOBLKS
    FROM V$UNDOSTAT;    
查询UNDO段统计信息
    SELECT a.name, b.xacts, b.writes, b.extents FROM v$rollname a, v$rollstat b WHERE a.usn=b.usn;
查询指定用户活动事务信息
    SELECT a.username, b.name, c.used_ublk FROM v$session a, v$rollname b, v$transaction c
    WHERE a.saddr=c.ses_addr AND b.usn=c.xidusn  AND a.username='HR';
查询数据行所在的文件号和块号
    select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid),id from t10;
查看当前会话的进程编号肯定dump出的trc文件
    select spid from v$process where addr in (select paddr from v$session where 
    sid=(select sid from v$mystat where rownum=1));
 .net

相关文章
相关标签/搜索