理解redo(3)详解一个update的过程


理论解析:

    1)server process 搜索buffer cache中是否有update要更新的block(内存中又名buffer),没有则从disk读入buffer cache

    2)server process 构造一组change vector来记录对数据块的改动(此时放于PGA中),这组change vector组成 redo record
            这里可能有4个数据块会被改动:
            回滚段的段头块:相应的事务表上标注事务信息,其中包括了xid,uba等;并且分配回滚块
            数据块的块头块:分配事务槽,标注事务信息,其中包含了xid,uba等
            回滚块:记录前镜像
            数据块:修改

   3)用redo record 的大小判断需要多少redo log buffer空间

   4)判断current scn,将其存到redo record(不同的redo record可能会共享同样的SCN值,用change vector header里面的值SEQ加以区别)

   5)获得redo copy latch,接着获得redo allocation latch

   6)查看当前是否有其它process比当前持有的SCN 更高的SCN值,有的话生成一个新SCN,替换第4步中的SCN。总之,保存最新的scn。

   7)判断是否有足够的redo log buffer空间,具体如下: 

如果redo log buffer没有足够空间,释放redo copy latch,redo allocation latch,释放后如果此时有其它进程或条件出发了LGWR则要等待lgwr完成,如果此时LGWR没启动,则触发lgwr 启动(需要redo writing latch,从LOG BUFFER 把redo record写入online current redo log file中时 LGWR进程会一直占着这个LATCH,防止其他process同时触发LGWR,其它process要尝试获得该latch必须等待,还会获得redo allocation latch 防止有新的change vector继续写入log buffer,造成LGWR无法确定应该写多少redo),当没有足够空间时,释放完redo copy/allocation latch后,会立刻尝试获取redo writing latch 获取不到 就表明lgwr被其他process启动了,等待,继续尝试,获取到后会先检查log buffer是否有空间了(因为前面LGWR 可能释放了大量redo log buffer空间)此时要是有空间了 释放redo writing latch,然后获得redo copy/allocation latch,没空间的话触发lgwr,并且释放redo writing latch(把这个latch给了lgwr).如果没有空间,且lgwr 将redo log buffer 里面的redo record 写入online current redo logfile时 ,redo logfile空间不足不够写入时,则process会检查是否有其它process启动了switch logfile,如果没有则触发switch logfile,有其他进程启动了,则当前进程等待,switch logfile 后,继续让lgwr写入redo log buffer .(注意switch log时候 禁止生成redo)

如果redo log buffer有足够的空间,则分配空间, 释放redo allocation latch,然后把change vector从PGA COPY到  redo log buffer,把redo record 对应在buffer cache中修改的block 挂到CKPTQ(checkpoint queue)上去(等dbwr写入)然后释放redo copy latch. 

    8)检查写完后的redo log buffer ,redo record是否达到threadshold,到了则触发lgwr

    9)更新buffer cache 中block

     具体实验(dump undo信息来理解):

    1)

  1. SQL> conn hr/hr  
  2. 已连接。  
  3. SQL> drop table t1;  
  4. drop table t1  
  5.            *  
  6. 第 1 行出现错误:  
  7. ORA-00942: 表或视图不存在  
  8. SQL> create table t1(id number,name varchar2(20));  
  9.   
  10. 表已创建。  
  11.   
  12. SQL> insert into t1(1,'a');  
  13. insert into t1(1,'a')  
  14.                *  
  15. 第 1 行出现错误:  
  16. ORA-00928: 缺失 SELECT 关键字  
  17.   
  18.   
  19. SQL> insert into t1 values(1,'a');  
  20.   
  21. 已创建 1 行。  
  22.   
  23. SQL> insert into t1 values(2,'b');  
  24.   
  25. 已创建 1 行。  
  26. SQL> commit;  
  27.   
  28. 提交完成。  
    2)
  1. SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,  
  2.   2         dbms_rowid.rowid_block_number(rowid) bno  
  3.   3    from hr.t1;  
  4.   
  5.        FNO        BNO  
  6. ---------- ----------   
  7.          4        437  
  8.          4        437  
  9.   
  10. SQL> select data_object_id,owner from dba_objects where object_name='T1';  
  11.   
  12. DATA_OBJECT_ID OWNER  
  13. -------------- ------------------------------------------------------------   
  14.          53467 HR  
  15.   
  16. SQL> alter system flush buffer_cache;  
  17.   
  18. 系统已更改。  
  19. SQL> select file#,block#,dirty from v$bh where objd=53467;  
  20.   
  21.      FILE#     BLOCK# DI  
  22. ---------- ---------- --   
  23.          4        438 N  
  24.          4        433 N  
  25.          4        436 N  
  26.          4        439 N  
  27.          4        434 N  
  28.          4        437 N  
  29.   
  30. 已选择6行。  

    3)

  1. SQL> select * from t1;  
  2.   
  3.         ID NAME  
  4. ---------- ----------------------------------------   
  5.          1 a  
  6.          2 b  
  7.   
  8. SQL> update t1 set name='c' where id=1;  
  9.   
  10. 已更新 1 行。  

    4)

  1. SQL> select file#,block#,dirty from v$bh where objd=53467;  
  2.   
  3.      FILE#     BLOCK# DI  
  4. ---------- ---------- --   
  5.          4        440 N  
  6.          4        435 N  
  7.          4        438 N  
  8.          4        438 N  
  9.          4        433 N  
  10.          4        436 N  
  11.          4        436 N  
  12.          4        439 N  
  13.          4        439 N  
  14.          4        434 N  
  15.          4        437 N  
  16.          4        437 N  
  17.          4        437 Y  
  18.   
  19. 已选择13行。  
  20.   
  21. SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk from v$transaction;  
  22.   
  23.     XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK  
  24. ---------- ---------- ---------- ---------- ----------   
  25.          8          6        579          2       2636  
  • 1
  • 2
  • 下一页

相关内容