ASSM三级位图结构与高水位的探究(下)

    上一篇文章介绍了ASSM三级位图管理下的数据插入和高水位推进的关系,我们得出的结论是随着数据不断的插入,段大小的不断增长,L1中挂载的数据块的数量也会增长,而高水位是以L1中数据块大小的总和区大小之间最小的一方为单位进行推进,而且我们知道要想应对大并发插入,就要使高水位之下的空闲块的数量尽可能多,但是如此一来就有可能造成空间的浪费,而oracle的初心也是本着节省空间的目的来设计的。
    之前我们用的是常规路径插入,能以L1和区的单位推动高水位,前提是要填满L1或区,而我们熟知的直接路径插入是在高水位之上插入,那是不是可以用直接路径插入快速增加高水位呢?我们来一探究竟。
    
    首先构造测试的表空间和表,跟上一篇一样

  1. SQL> drop tablespace lp including contents and datafiles;

  2. Tablespace dropped.

  3. SQL> create tablespace lp datafile '/home/oracle/app/oracle/oradata/DG43/lp.dbf' size 2048M uniform size 1m;
  4. create table lp (id number,des1 char(2000),des2 char(2000),des3 char(2000),des4 char(500)) tablespace lp;

  5. Tablespace created.

  6. SQL>
  7. Table created.

  8. SQL> alter table lp pctfree 24;

  9. Table altered.


  10. SQL> select object_id,object_name from dba_objects where object_name='LP';

  11.  OBJECT_ID OBJECT_NAME
  12. ---------- ------------------------------
  13.      78760 LP
首先看一下,78760这个对象在buffer里的数据块有哪些
  1. SQL> select file#,BLOCK#,DIRTY,OBJD from v$bh where objd='78760';

  2.      FILE# BLOCK# D OBJD
  3. ---------- ---------- - ----------
  4.          5 131 N 78760
  5.          5 129 N 78760
  6.          5 130 N 78760
  7.          5 128 N 78760
有没有眼熟呢,128、129、130、131四个块刚好是两个L1、L2、L3
我们定位段头块,看一下此时的高水位
  1. SQL> select segment_name ,HEADER_FILE,HEADER_BLOCK from dba_segments where segment_name='LP';
  2. SEGMENT_NAME HEADER_FILE HEADER_BLOCK
  3. ------------------------------ ----------- ------------
  4. LP 5 131
  5. Extent Control Header
  6. -----------------------------------------------------------------
  7. Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 128
  8. last map 0x00000000 #maps: 0 offset: 2716
  9. Highwater:: 0x01400084 ext#: 0 blk#: 4 ext size: 128
  10. #blocks in seg. hdr's freelists: 0
  11. #blocks below: 0
  12. mapblk 0x00000000 offset: 0
  13. SQL> select dbms_utility.data_block_address_file(to_number('01400084', 'xxxxxxxx')) file#,
  14. 2 dbms_utility.data_block_address_block(to_number('01400084', 'xxxxxxxx')) block#
  15. 3 from dual;
  16. FILE# BLOCK#
  17. ---------- ----------
  18. 5 132
可以看出在没有任何数据的情况下,高水位是在第一个数据块上的,下面常规插入一行数据
  1. insert into lp values(1,'a','a','a','a');
看一下高水位和buffer中的块
  1. SQL> select file#,BLOCK#,DIRTY,OBJD from v$bh where objd='78760';

  2.      FILE# BLOCK# D OBJD
  3. ---------- ---------- - ----------
  4.          5 165 Y 78760
  5.          5 131 Y 78760
  6.          5 173 Y 78760
  7.          5 160 Y 78760
  8.          5 168 Y 78760
  9.          5 163 Y 78760
  10.          5 129 N 78760
  11.          5 171 Y 78760
  12.          5 166 Y 78760
  13.          5 174 Y 78760
  14.          5 161 Y 78760

  15.      FILE# BLOCK# D OBJD
  16. ---------- ---------- - ----------
  17.          5 169 Y 78760
  18.          5 164 Y 78760
  19.          5 130 N 78760
  20.          5 172 Y 78760
  21.          5 167 Y 78760
  22.          5 175 Y 78760
  23.          5 162 Y 78760
  24.          5 128 Y 78760
  25.          5 170 Y 78760

  26. 20 rows selected.

  27. SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from lp;

  28. DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
  29. ------------------------------------ ------------------------------------
  30.                                    5 160

  1. Extent Control Header
  2. -----------------------------------------------------------------
  3. Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 128
  4. last map 0x00000000 #maps: 0 offset: 2716
  5. Highwater:: 0x014000c0 ext#: 0 blk#: 64 ext size: 128
  6. #blocks in seg. hdr's freelists: 0
  7. #blocks below: 60
  8. mapblk 0x00000000 offset: 0

发现数据插入到160号块中,buffer中却多了16个块,高水位已移动到第二个L1中的第一个块上,看一下第一个L1
  1. HWM Flag: HWM Set
  2. Highwater:: 0x014000c0 ext#: 0 blk#: 64 ext size: 128
  3. #blocks in seg. hdr's freelists: 0
  4. #blocks below: 60
  5. mapblk 0x00000000 offset: 0
  6. --------------------------------------------------------
  7. DBA Ranges :
  8. --------------------------------------------------------
  9. 0x01400080 Length: 64 Offset: 0
  10. 0:Metadata 1:Metadata 2:Metadata 3:Metadata
  11. 4:unformatted 5:unformatted 6:unformatted 7:unformatted
  12. 8:unformatted 9:unformatted 10:unformatted 11:unformatted
  13. 12:unformatted 13:unformatted 14:unformatted 15:unformatted
  14. 16:unformatted 17:unformatted 18:unformatted 19:unformatted
  15. 20:unformatted 21:unformatted 22:unformatted 23:unformatted
  16. 24:unformatted 25:unformatted 26:unformatted 27:unformatted
  17. 28:unformatted 29:unformatted 30:unformatted 31:unformatted
  18. 32:FULL 33:75-100% free 34:75-100% free 35:75-100% free
  19. 36:75-100% free 37:75-100% free 38:75-100% free 39:75-100% free
  20. 40:75-100% free 41:75-100% free 42:75-100% free 43:75-100% free
  21. 44:75-100% free 45:75-100% free 46:75-100% free 47:75-100% free
  22. 48:unformatted 49:unformatted 50:unformatted 51:unformatted
  23. 52:unformatted 53:unformatted 54:unformatted 55:unformatted
  24. 56:unformatted 57:unformatted 58:unformatted 59:unformatted
  25. 60:unformatted 61:unformatted 62:unformatted 63:unformatted

  1. SQL> select dbms_utility.data_block_address_file(to_number('014000c0', 'xxxxxxxx')) file#,
  2.   2 dbms_utility.data_block_address_block(to_number('014000c0', 'xxxxxxxx')) block#
  3.   3 from dual;

  4.      FILE# BLOCK#
  5. ---------- ----------
  6.          5 192
可以发现,buffer中新增的16个块是一次性格式化的这16个块,而高水位指在192号块上,直接路径插入一行
  1. SQL> select file#,BLOCK#,DIRTY,OBJD from v$bh where objd='78760';

  2.      FILE# BLOCK# D OBJD
  3. ---------- ---------- - ----------
  4.          5 165 N 78760
  5.          5 131 N 78760
  6.          5 173 N 78760
  7.          5 160 N 78760
  8.          5 168 N 78760
  9.          5 163 N 78760
  10.          5 129 N 78760
  11.          5 171 N 78760
  12.          5 166 N 78760
  13.          5 174 N 78760
  14.          5 161 N 78760

  15.      FILE# BLOCK# D OBJD
  16. ---------- ---------- - ----------
  17.          5 169 N 78760
  18.          5 164 N 78760
  19.          5 130 N 78760
  20.          5 172 N 78760
  21.          5 167 N 78760
  22.          5 175 N 78760
  23.          5 162 N 78760
  24.          5 128 N 78760
  25.          5 170 N 78760

  26. 20 rows selected.


  27. SQL> insert /*+ append_values(lp)*/ into lp values(2,'b','b','b','b');

  28. 1 row created.

  29. SQL> commit;

  30. Commit complete.

  31. SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from lp;

  32. DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
  33. ------------------------------------ ------------------------------------
  34.                                    5 160
  35.                                    5 192

  36. SQL> select file#,BLOCK#,DIRTY,OBJD from v$bh where objd='78760';

  37.      FILE# BLOCK# D OBJD
  38. ---------- ---------- - ----------
  39.          5 165 N 78760
  40.          5 131 Y 78760
  41.          5 173 N 78760
  42.          5 160 N 78760
  43.          5 168 N 78760
  44.          5 163 N 78760
  45.          5 129 Y 78760
  46.          5 171 N 78760
  47.          5 192 Y 78760
  48.          5 166 N 78760
  49.          5 174 N 78760

  50.      FILE# BLOCK# D OBJD
  51. ---------- ---------- - ----------
  52.          5 161 N 78760
  53.          5 169 N 78760
  54.          5 164 N 78760
  55.          5 130 N 78760
  56.          5 172 N 78760
  57.          5 167 N 78760
  58.          5 175 N 78760
  59.          5 162 N 78760
  60.          5 128 Y 78760
  61.          5 170 N 78760

  62. 21 rows selected.

  63. SQL> alter system checkpoint;

  64. System altered.
确实插入到了192号块,看一下此时的高水位
  1. Extent Control Header
  2. -----------------------------------------------------------------
  3. Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 128
  4. last map 0x00000000 #maps: 0 offset: 2716
  5. Highwater:: 0x014000c1 ext#: 0 blk#: 65 ext size: 128
  6. #blocks in seg. hdr's freelists: 0
  7. #blocks below: 65
  8. mapblk 0x00000000 offset: 0
  9. HWM Flag: HWM Set
  10. Highwater:: 0x014000c1 ext#: 0 blk#: 65 ext size: 128
  11. #blocks in seg. hdr's freelists: 0
  12. #blocks below: 65
  13. mapblk 0x00000000 offset: 0
  14. --------------------------------------------------------
  15. DBA Ranges :
  16. --------------------------------------------------------
  17. 0x014000c0 Length: 64 Offset: 0
  18. 0:FULL 1:unformatted 2:unformatted 3:unformatted
  19. 4:unformatted 5:unformatted 6:unformatted 7:unformatted
  20. 8:unformatted 9:unformatted 10:unformatted 11:unformatted
  21. 12:unformatted 13:unformatted 14:unformatted 15:unformatted
  22. 16:unformatted 17:unformatted 18:unformatted 19:unformatted
  23. 20:unformatted 21:unformatted 22:unformatted 23:unformatted
  24. 24:unformatted 25:unformatted 26:unformatted 27:unformatted
  25. 28:unformatted 29:unformatted 30:unformatted 31:unformatted
  26. 32:unformatted 33:unformatted 34:unformatted 35:unformatted
  27. 36:unformatted 37:unformatted 38:unformatted 39:unformatted
  28. 40:unformatted 41:unformatted 42:unformatted 43:unformatted
  29. 44:unformatted 45:unformatted 46:unformatted 47:unformatted
  30. 48:unformatted 49:unformatted 50:unformatted 51:unformatted
  31. 52:unformatted 53:unformatted 54:unformatted 55:unformatted
  32. 56:unformatted 57:unformatted 58:unformatted 59:unformatted
  33. 60:unformatted 61:unformatted 62:unformatted 63:unformatted
  34. --------------------------------------------------------
  35. End dump data blocks tsn: 5 file#: 5 minblk 129 maxblk 129
发现高水位仅仅移动了1个block,再试一遍
  1. SQL> insert /*+ append_values(lp)*/ into lp values(3,'c','c','c','c');

  2. 1 row created.

  3. SQL> commit;

  4. Commit complete.

  5. SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from lp;

  6. DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
  7. ------------------------------------ ------------------------------------
  8.                                    5 160
  9.                                    5 192
  10.                                    5 193

  11. SQL> select file#,BLOCK#,DIRTY,OBJD from v$bh where objd='78760';

  12.      FILE# BLOCK# D OBJD
  13. ---------- ---------- - ----------
  14.          5 165 N 78760
  15.          5 131 Y 78760
  16.          5 173 N 78760
  17.          5 160 N 78760
  18.          5 168 N 78760
  19.          5 163 N 78760
  20.          5 129 Y 78760
  21.          5 171 N 78760
  22.          5 192 N 78760
  23.          5 166 N 78760
  24.          5 174 N 78760

  25.      FILE# BLOCK# D OBJD
  26. ---------- ---------- - ----------
  27.          5 161 N 78760
  28.          5 169 N 78760
  29.          5 164 N 78760
  30.          5 130 N 78760
  31.          5 172 N 78760
  32.          5 193 Y 78760
  33.          5 167 N 78760
  34.          5 175 N 78760
  35.          5 162 N 78760
  36.          5 128 N 78760
  37.          5 170 N 78760

  38. 22 rows selected.

  1. Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 128
  2. last map 0x00000000 #maps: 0 offset: 2716
  3. Highwater:: 0x014000c2 ext#: 0 blk#: 66 ext size: 128
  4. #blocks in seg. hdr's freelists: 0
  5. #blocks below: 66
  6. mapblk 0x00000000 offset: 0
仍然是只推动了一个block,但是发现为何每次直接路径插入的block都会出现在buffer里呢?难道是11g这个 append_values新的hint的原因,再来试一下传统的append
  1. SQL> insert /*+ append*/ into lp select * from lp where trim(des1)='a';

  2. 1 row created.

  3. SQL> commit;

  4. Commit complete.

  5. SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from lp;

  6. DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
  7. ------------------------------------ ------------------------------------
  8.                                    5 160
  9.                                    5 192
  10.                                    5 193
  11.                                    5 194

  12. SQL> select file#,BLOCK#,DIRTY,OBJD from v$bh where objd='78760';

  13.      FILE# BLOCK# D OBJD
  14. ---------- ---------- - ----------
  15.          5 165 N 78760
  16.          5 131 Y 78760
  17.          5 173 N 78760
  18.          5 194 Y 78760
  19.          5 160 N 78760
  20.          5 168 N 78760
  21.          5 163 N 78760
  22.          5 129 Y 78760
  23.          5 171 N 78760
  24.          5 192 N 78760
  25.          5 166 N 78760

  26.      FILE# BLOCK# D OBJD
  27. ---------- ---------- - ----------
  28.          5 174 N 78760
  29.          5 161 N 78760
  30.          5 169 N 78760
  31.          5 164 N 78760
  32.          5 130 N 78760
  33.          5 172 N 78760
  34.          5 193 N 78760
  35.          5 167 N 78760
  36.          5 175 N 78760
  37.          5 162 N 78760
  38.          5 128 N 78760

  39.      FILE# BLOCK# D OBJD
  40. ---------- ---------- - ----------
  41.          5 170 N 78760

  42. 23 rows selected.
依然如故,不知道大家有没有发现,每次我执行完插入,都会执行一条select dbms_rowid.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from lp;
这其实是全表扫描,本来块没在buffer里,一个FTS把块全给整进来了(小表buffer读,大表在11g中通常情况是直接路径读),知道原因了,再试一遍
  1. SQL> insert /*+ append*/ into lp select * from lp where trim(des1)='b';

  2. 1 row created.

  3. SQL> commit;

  4. Commit complete.

  5. SQL> select file#,BLOCK#,DIRTY,OBJD from v$bh where objd='78760';

  6.      FILE# BLOCK# D OBJD
  7. ---------- ---------- - ----------
  8.          5 165 N 78760
  9.          5 131 Y 78760
  10.          5 173 N 78760
  11.          5 194 N 78760
  12.          5 160 N 78760
  13.          5 168 N 78760
  14.          5 163 N 78760
  15.          5 129 Y 78760
  16.          5 171 N 78760
  17.          5 192 N 78760
  18.          5 166 N 78760

  19.      FILE# BLOCK# D OBJD
  20. ---------- ---------- - ----------
  21.          5 174 N 78760
  22.          5 161 N 78760
  23.          5 169 N 78760
  24.          5 164 N 78760
  25.          5 130 N 78760
  26.          5 172 N 78760
  27.          5 193 N 78760
  28.          5 167 N 78760
  29.          5 175 N 78760
  30.          5 162 N 78760
  31.          5 128 N 78760

  32.      FILE# BLOCK# D OBJD
  33. ---------- ---------- - ----------
  34.          5 170 N 78760

  35. 23 rows selected.

  36. SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from lp;

  37. DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
  38. ------------------------------------ ------------------------------------
  39.                                    5 160
  40.                                    5 192
  41.                                    5 193
  42.                                    5 194
  43.                                    5 195

  44. SQL> select file#,BLOCK#,DIRTY,OBJD from v$bh where objd='78760';

  45.      FILE# BLOCK# D OBJD
  46. ---------- ---------- - ----------
  47.          5 165 N 78760
  48.          5 131 Y 78760
  49.          5 173 N 78760
  50.          5 194 N 78760
  51.          5 160 N 78760
  52.          5 168 N 78760
  53.          5 163 N 78760
  54.          5 129 Y 78760
  55.          5 171 N 78760
  56.          5 192 N 78760
  57.          5 166 N 78760

  58.      FILE# BLOCK# D OBJD
  59. ---------- ---------- - ----------
  60.          5 174 N 78760
  61.          5 195 Y 78760
  62.          5 161 N 78760
  63.          5 169 N 78760
  64.          5 164 N 78760
  65.          5 130 N 78760
  66.          5 172 N 78760
  67.          5 193 N 78760
  68.          5 167 N 78760
  69.          5 175 N 78760
  70.          5 162 N 78760

  71.      FILE# BLOCK# D OBJD
  72. ---------- ---------- - ----------
  73.          5 128 N 78760
  74.          5 170 N 78760

  75. 24 rows selected.
终于看到了想要的结果,总结一下吧,直接路径下高水位的推进大概如下图的样子:


不知道大家有没有注意到,直接路径插入完后再读入buffer中居然是个脏块,这是不是跟延迟提交清除有关呢?我们以后再慢慢分析!



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

转载于:http://blog.itpub.net/26838672/viewspace-1812306/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值