Oracle In Memory Undo(转)

Oracle In Memory Undo

作者: fuyuncat

来源: www.HelloDBA.com

    IMU was first introduced in 10g, but I can not observe it in my 10.2.0.3 server. Below test was performed in 11g.
 

    In traditional undo update, once record be updated, an undo block will be allocated in the buffer cache, 1 new entry will be inserted into the undo block immediately. If several records be updated in the same transaction, several entries generated in the undo buffer as soon as the record updated. At the mean time, each undo entry will also generate redo log entry. After introduced the IMU, new pools named IMU pools will be allocated from shared pool. Once a record be updated, an undo buffer block still be allocted from buffer cache, but without inserting a new entry into the block immediately. It will generate an undo map in the IMU pool, and one IMU node for the record change. If several records be updated, several IMU nodes will be generated in the IMU pool, and the UNDO map be updated correspondly. All of the changes occur in the IMU pool, not modify the undo buffer block. Once commit or the IMU pool be flushed, it will map the IMU nodes as undo entries into the undo block and write to disk. This process is a batch process, just 1 redo entry generated for these changes.
 

    The undocumented parameter "_in_memory_undo" control to enable/disable this feature. It could be modified in system/session level. Another undocumented parameter "_IMU_pools" control the IMU pool number.

SQL代码
  1. HELLODBA.COM>create table ttt (a number, b varchar2(20));   
  2.   
  3. Table created.   
  4.   
  5. HELLODBA.COM>begin  
  6.   2    for i in 1..2000 loop   
  7.   3      insert into ttt values (i, ''||i);   
  8.   4    end loop;   
  9.   5    commit;   
  10.   6  end;   
  11.   7  /   
  12.   
  13. PL/SQL procedure successfully completed.   
  14.   
  15. HELLODBA.COM>select a   
  16.   2  from (select a, dbms_rowid.rowid_block_number(ROWID) block_id, lag(dbms_rowid.rowid_block_number(ROWID)) over (order by rowid) as pre_block_id from ttt)   
  17.   3  where block_id != pre_block_id;   
  18.   
  19.          A   
  20. ----------   
  21.       1124   
  22.       1643   
  23.          1  

IMU Commit

    Let's have a testing to see how does IMU reduce redo size.

    First observe the traditional mode.

SQL代码
  1. HELLODBA.COM>conn demo/demo@ora11   
  2. Connected.   
  3. HELLODBA.COM>alter session set "_in_memory_undo"=false;   
  4.   
  5. Session altered.   
  6.   
  7. HELLODBA.COM>update ttt set b='X' where a=1124;   
  8.   
  9. 1 row updated.   
  10.   
  11. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# and b.name in ('redo entries''redo size''IMU commits');   
  12.   
  13. NAME                                                                  VALUE   
  14. ---------------------------------------------------------------- ----------   
  15. redo entries                                                              4   
  16. redo size                                                              1600   
  17. IMU commits                                                               0   
  18.   
  19. HELLODBA.COM>update ttt set b='Y' where a=1643;   
  20.   
  21. 1 row updated.   
  22.   
  23. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# and b.name in ('redo entries''redo size''IMU commits');   
  24.   
  25. NAME                                                                  VALUE   
  26. ---------------------------------------------------------------- ----------   
  27. redo entries                                                              5   
  28. redo size                                                              1960   
  29. IMU commits                                                               0   
  30.   
  31. HELLODBA.COM>update ttt set b='Z' where a=1;   
  32.   
  33. 1 row updated.   
  34.   
  35. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# and b.name in ('redo entries''redo size''IMU commits');   
  36.   
  37. NAME                                                                  VALUE   
  38. ---------------------------------------------------------------- ----------   
  39. redo entries                                                              6   
  40. redo size                                                              2320   
  41. IMU commits                                                               0   
  42.   
  43. HELLODBA.COM>commit;   
  44.   
  45. Commit complete.   
  46.   
  47. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# and b.name in ('redo entries''redo size''IMU commits');   
  48.   
  49. NAME                                                                  VALUE   
  50. ---------------------------------------------------------------- ----------   
  51. redo entries                                                              7   
  52. redo size                                                              2416   
  53. IMU commits                                                               0  

    Each record updating generate 1 redo entry.
 

    Now, enable IMU and do it again.
 

SQL代码
  1. HELLODBA.COM>conn demo/demo@ora11   
  2. Connected.   
  3. HELLODBA.COM>alter session set "_in_memory_undo"=true;   
  4.   
  5. Session altered.   
  6.   
  7. HELLODBA.COM>update ttt set b='X' where a=1124;   
  8.   
  9. 1 row updated.   
  10.   
  11. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# an   
  12. d b.name in ('redo entries''redo size''IMU commits');   
  13.   
  14. NAME                                                                  VALUE   
  15. ---------------------------------------------------------------- ----------   
  16. redo entries                                                              3   
  17. redo size                                                              1084   
  18. IMU commits                                                               0   
  19.   
  20. HELLODBA.COM>update ttt set b='Y' where a=1643;   
  21.   
  22. 1 row updated.   
  23.   
  24. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# an   
  25. d b.name in ('redo entries''redo size''IMU commits');   
  26.   
  27. NAME                                                                  VALUE   
  28. ---------------------------------------------------------------- ----------   
  29. redo entries                                                              3   
  30. redo size                                                              1084   
  31. IMU commits                                                               0   
  32.   
  33. HELLODBA.COM>update ttt set b='Z' where a=1;   
  34.   
  35. 1 row updated.   
  36.   
  37. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# an   
  38. d b.name in ('redo entries''redo size''IMU commits');   
  39.   
  40. NAME                                                                  VALUE   
  41. ---------------------------------------------------------------- ----------   
  42. redo entries                                                              3   
  43. redo size                                                              1084   
  44. IMU commits                                                               0   
  45.   
  46. HELLODBA.COM>commit;   
  47.   
  48. Commit complete.   
  49.   
  50. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# an   
  51. d b.name in ('redo entries''redo size''IMU commits');   
  52.   
  53. NAME                                                                  VALUE   
  54. ---------------------------------------------------------------- ----------   
  55. redo entries                                                              4   
  56. redo size                                                              2176   
  57. IMU commits                                                               1  

    The redo entries did not increase with the records be updated, it just increase at the momemt commmit. Unlike traditional commit redo entry, it not only contain the commit vector, but also the undo changes, be wroten in batch.

    IMU commit also works in such case that several records updated in 1 dml.
 

SQL代码
  1. HELLODBA.COM>conn demo/demo@ora11   
  2. Connected.   
  3. HELLODBA.COM>alter session set "_in_memory_undo"=true;   
  4.   
  5. Session altered.   
  6.   
  7. HELLODBA.COM>update ttt set b='X' where a in (1643, 1124, 1);   
  8.   
  9. rows updated.   
  10.   
  11. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# an   
  12. d b.name in ('redo entries''redo size''IMU commits');   
  13.   
  14. NAME                                                                  VALUE   
  15. ---------------------------------------------------------------- ----------   
  16. redo entries                                                              3   
  17. redo size                                                              1084   
  18. IMU commits                                                               0   
  19.   
  20. HELLODBA.COM>commit;   
  21.   
  22. Commit complete.   
  23.   
  24. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# an   
  25. d b.name in ('redo entries''redo size''IMU commits');   
  26.   
  27. NAME                                                                  VALUE   
  28. ---------------------------------------------------------------- ----------   
  29. redo entries                                                              4   
  30. redo size                                                              2344   
  31. IMU commits                                                               1  

    You may noted although the final redo size of IMU is less than the redo size of non-IMU, it increased obviously when commit. Dump the redo entry, we can find it contains the changes before commit, including the recursive operations, such as cleanout.
 

SQL代码
  1. HELLODBA.COM>conn demo/demo@ora11   
  2. Connected.   
  3. HELLODBA.COM>set serveroutput on  
  4. HELLODBA.COM>var v_bt number;   
  5. HELLODBA.COM>var v_et number;   
  6. HELLODBA.COM>alter session set "_in_memory_undo"=false;   
  7.   
  8. Session altered.   
  9.   
  10. HELLODBA.COM>update tt set x=1 where rownum <= 1;   
  11.   
  12. 1 row updated.   
  13.   
  14. HELLODBA.COM>update tt set x=2 where rownum <= 1;   
  15.   
  16. 1 row updated.   
  17.   
  18. HELLODBA.COM>update tt set x=3 where rownum <= 1;   
  19.   
  20. 1 row updated.   
  21.   
  22. HELLODBA.COM>begin  
  23.   2   select current_scn into :v_bt from v$database;   
  24.   3   dbms_output.put_line(''||:v_bt);   
  25.   4  end;   
  26.   5  /   
  27. 6328064   
  28.   
  29. PL/SQL procedure successfully completed.   
  30.   
  31. HELLODBA.COM>commit;   
  32.   
  33. Commit complete.   
  34.   
  35. HELLODBA.COM>begin  
  36.   2   select current_scn into :v_et from v$database;   
  37.   3   dbms_output.put_line(''||:v_et);   
  38.   4  end;   
  39.   5  /   
  40. 6328067   
  41.   
  42. PL/SQL procedure successfully completed.   
  43.   
  44. HELLODBA.COM>declare  
  45.   2   v_log varchar2(2000);   
  46.   3   v_sql varchar2(4000);   
  47.   4  begin  
  48.   5   select a.member into v_log from v$logfile a, v$log b where a.group#=b.groupand b.status='CUR  
  49. RENT' and rownum <= 1;   
  50.   6   execute immediate 'alter system switch logfile';   
  51.   7   v_sql := 'alter system dump logfile '''||v_log||''' SCN MIN '||:v_bt||' SCN MAX '||:v_et;   
  52.   8   execute immediate v_sql;   
  53.   9  end;   
  54.  10  /   
  55.   
  56. PL/SQL procedure successfully completed.  

    In the redo trace file, there are 3 changes in this entry.
 

SQL代码
  1. REDO RECORD - Thread:1 RBA: 0x0000c8.00000f39.0010 LEN: 0x046c VLD: 0x0d   
  2. SCN: 0x0000.00608ed4 SUBSCN:  1 11/16/2009 14:59:10   
  3. CHANGE #1 TYP:2 CLS: 1 AFN:4 DBA:0x010016cf OBJ:74952 SCN:0x0000.00602dc7 SEQ:  4 OP:11.19   
  4. KTB Redo    
  5. ...   
  6. CHANGE #2 TYP:0 CLS:17 AFN:3 DBA:0x00c00009 OBJ:4294967295 SCN:0x0000.00608e9b SEQ:  2 OP:5.2   
  7. ...   
  8. CHANGE #8 TYP:0 CLS:18 AFN:3 DBA:0x00c006f7 OBJ:4294967295 SCN:0x0000.00608ed4 SEQ:  2 OP:5.1   
  9. ...  

    Once commit, the IMU nodes will be mapped to undo buffer block, after that, the undo buffer block is same as the non-IMU undo buffer block.
 

IMU Flush

    The IMU pool is also managed by LRU algorithm. Once not enough buffer could be allocated for the new transactions, it will flush the buffers from the LRU end. Other events will also cause the IMU flush, such as switch logfile and tansaction rollback. However, even though the IMU pools were mentioned as allocated from shared pool, manually flushing shared pool will not cause the IMU flush. Once IMU nodes be flushed, the undo entries will be mapped into the correspond undo buffer.
 

SQL代码
  1. HELLODBA.COM>conn demo/demo@ora11   
  2. Connected.   
  3. HELLODBA.COM>alter session set "_in_memory_undo"=true;   
  4.   
  5. Session altered.   
  6.   
  7. HELLODBA.COM>update tt set x=1;   
  8.   
  9. 1 row updated.   
  10.   
  11. HELLODBA.COM>update tt set x=2;   
  12.   
  13. 1 row updated.   
  14.   
  15. HELLODBA.COM>update tt set x=3;   
  16.   
  17. 1 row updated.   
  18.   
  19. HELLODBA.COM>select b.name, a.value from v$sysstat a, v$statname b where a.statistic#=b.statistic# and b.name like '%IMU%';   
  20.   
  21. NAME                                                                  VALUE   
  22. ---------------------------------------------------------------- ----------   
  23. IMU commits                                                             320   
  24. IMU Flushes                                                             159   
  25. IMU contention                                                           19   
  26. ...   
  27.   
  28. 13 rows selected.   
  29.   
  30. HELLODBA.COM>alter system switch logfile;   
  31.   
  32. System altered.   
  33.   
  34. HELLODBA.COM>select b.name, a.value from v$sysstat a, v$statname b where a.statistic#=b.statistic# and b.name like '%IMU%';   
  35.   
  36. NAME                                                                  VALUE   
  37. ---------------------------------------------------------------- ----------   
  38. IMU commits                                                             320   
  39. IMU Flushes                                                             160   
  40. IMU contention                                                           20   
  41. ...   
  42.   
  43. 13 rows selected.  

    Once flushed, all of the changes after last flush will be merged into 1 redo log entry.
 

IMU CR

    In traditional mode, the consistent get transaction will read undo block to apply the undo records. However, in IMU, the undo buffer block was not be modified before IMU commit/flush, the CR transaction need read the undo info from IMU pool.
 

SQL代码
  1. --Session 1:   
  2. HELLODBA.COM>conn demo/demo@ora11   
  3. Connected.   
  4. HELLODBA.COM>alter session set "_in_memory_undo"=true;   
  5.   
  6. Session altered.   
  7.   
  8. HELLODBA.COM>update tt set x=1;   
  9.   
  10. 1 row updated.   
  11.   
  12. HELLODBA.COM>update tt set x=2;   
  13.   
  14. 1 row updated.   
  15.   
  16. HELLODBA.COM>update tt set x=3;   
  17.   
  18. 1 row updated.   
  19.   
  20. --Session 2:   
  21. HELLODBA.COM>conn demo/demo@ora11   
  22. Connected.   
  23. HELLODBA.COM>alter system flush buffer_cache;   
  24.   
  25. System altered.   
  26.   
  27. HELLODBA.COM>alter session set tracefile_identifier=IMU_CR;   
  28.   
  29. Session altered.   
  30.   
  31. HELLODBA.COM>alter session set events '10046 trace name context forever, level 8';   
  32.   
  33. Session altered.   
  34.   
  35. HELLODBA.COM>select * from tt;   
  36.   
  37.          X   
  38. ----------   
  39.          3   
  40.   
  41. HELLODBA.COM>alter session set events '10046 trace name context off';   
  42.   
  43. Session altered.   
  44.   
  45. HELLODBA.COM>select b.name, a.value from v$mystat a, v$statname b where a.statistic#=b.statistic# and b.name like '%IMU%';   
  46.   
  47. NAME                                                                  VALUE   
  48. ---------------------------------------------------------------- ----------   
  49. ...   
  50. IMU CR rollbacks                                                          3   
  51. ...  

     From the trace file, even though the undo buffer has been flushed out from buffer cached, it did not read the undo files for CR rollback, read from IMU pool instead.

    --- Fuyuncat Mark ---

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7199859/viewspace-671679/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7199859/viewspace-671679/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值