Oracle数据库数据恢复、性能优化

找回密码
注册
搜索
热搜: 活动 交友 discuz
发新帖

86

积分

0

好友

4

主题
1#
发表于 2012-5-23 16:03:19 | 查看: 5679| 回复: 4
问一个关于Data block的问题:当改变row中一个column的value从一个大值,到一个值,会释放一点空间,如果这个空间在row data段的中部,这段空间,怎么被新的记录使用呀? 难道上部的row data会向下移动?就像一个队列里移除一个元素,其后的元素都向前移动一个位置?
datablock.jpg
希望刘大能举点直观的例子:)
2#
发表于 2012-5-23 20:23:26
ODM TEST:
  1. Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
  2. With the Partitioning, OLAP, Data Mining and Real Application Testing options

  3. SQL>
  4. SQL> create table test_space(t1 varchar2(90));

  5. Table created.

  6. SQL> insert into test_space values ( rpad('Maclean',20,'Z'));

  7. 1 row created.

  8. SQL> insert into test_space values ( rpad('Maclean',20,'A'));

  9. 1 row created.

  10. SQL> insert into test_space values ( rpad('Maclean',20,'S'));

  11. 1 row created.

  12. SQL> commit;

  13. Commit complete.

  14. SQL> select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from test_space;

  15. DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
  16. ------------------------------------ ------------------------------------
  17.                                90306                                    1
  18.                                90306                                    1
  19.                                90306                                    1

  20. SQL> alter system checkpoint;

  21. System altered.

  22. SQL> alter system dump datafile 1 block 90306;

  23. System altered.


  24. SQL> oradebug setmypid
  25. Statement processed.


  26. SQL> oradebug tracefile_name
  27. /s01/admin/G10R25/udump/g10r25_ora_11763.trc

  28. SQL> select dump(t1,16),t1 from test_space;

  29. DUMP(T1,16)
  30. --------------------------------------------------------------------------------
  31. T1
  32. --------------------------------------------------
  33. Typ=1 Len=20: 4d,61,63,6c,65,61,6e,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a
  34. MacleanZZZZZZZZZZZZZ

  35. Typ=1 Len=20: 4d,61,63,6c,65,61,6e,41,41,41,41,41,41,41,41,41,41,41,41,41
  36. MacleanAAAAAAAAAAAAA

  37. Typ=1 Len=20: 4d,61,63,6c,65,61,6e,53,53,53,53,53,53,53,53,53,53,53,53,53
  38. MacleanSSSSSSSSSSSSS

  39. tab 0, row 0, @0x1f88
  40. tl: 24 fb: --H-FL-- lb: 0x1  cc: 1
  41. col  0: [20]  4d 61 63 6c 65 61 6e 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a
  42. tab 0, row 1, @0x1f70
  43. tl: 24 fb: --H-FL-- lb: 0x1  cc: 1
  44. col  0: [20]  4d 61 63 6c 65 61 6e 41 41 41 41 41 41 41 41 41 41 41 41 41
  45. tab 0, row 2, @0x1f58
  46. tl: 24 fb: --H-FL-- lb: 0x1  cc: 1
  47. col  0: [20]  4d 61 63 6c 65 61 6e 53 53 53 53 53 53 53 53 53 53 53 53 53
  48. end_of_block_dump



  49. row 0    offset 8072         MacleanZZZZZZZZZZZZZ           24bytes
  50. row 1    offset 8048         MacleanAAAAAAAAAAAAA           24bytes
  51. row 2    offset 8024         MacleanSSSSSSSSSSSSS           24bytes


  52. 即实际存储是
  53. ---------------
  54. block header  |
  55. FREE SPACE    |
  56. row2          |
  57. row1          |
  58. row0          |
  59. tail          |
  60. ---------------


  61. SQL> update test_space set t1='a' where t1='MacleanAAAAAAAAAAAAA';

  62. 1 row updated.

  63. SQL> alter system checkpoint;

  64. System altered.



  65. tab 0, row 0, @0x1f88
  66. tl: 24 fb: --H-FL-- lb: 0x0  cc: 1
  67. col  0: [20]  4d 61 63 6c 65 61 6e 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a
  68. tab 0, row 1, @0x1f53
  69. tl: 5 fb: --H-FL-- lb: 0x2  cc: 1
  70. col  0: [ 1]  61
  71. tab 0, row 2, @0x1f58
  72. tl: 24 fb: --H-FL-- lb: 0x0  cc: 1
  73. col  0: [20]  4d 61 63 6c 65 61 6e 53 53 53 53 53 53 53 53 53 53 53 53 53




  74. row0   offset 8072   MacleanZZZZZZZZZZZZZ   24bytes
  75. row1   offset 8019   a                      5bytes
  76. row2   offset 8024   MacleanSSSSSSSSSSSSS   24bytes

  77. 更新row1 后变成了

  78. ------------------
  79. block header     |
  80. FREE SPACE       |
  81. row1             |
  82. row2             |
  83. row0             |
  84. tail             |
  85. ------------------




  86. row2 出于row1 、 row0之间,对row2做更新 扩展

  87. SQL> update test_space set t1=rpad('Maclean',80,'Y') where t1='MacleanSSSSSSSSSSSSS';

  88. 1 row updated.

  89. SQL> commit;

  90. Commit complete.

  91. SQL> alter system checkpoint;

  92. System altered.

  93. SQL>  alter system dump datafile 1 block 90306;

  94. System altered.




  95. tab 0, row 0, @0x1f88
  96. tl: 24 fb: --H-FL-- lb: 0x0  cc: 1
  97. col  0: [20]  4d 61 63 6c 65 61 6e 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a
  98. tab 0, row 1, @0x1f53
  99. tl: 5 fb: --H-FL-- lb: 0x2  cc: 1
  100. col  0: [ 1]  61
  101. tab 0, row 2, @0x1eff
  102. tl: 84 fb: --H-FL-- lb: 0x1  cc: 1
  103. col  0: [80]
  104. 4d 61 63 6c 65 61 6e 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59
  105. 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59
  106. 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59
  107. 59 59 59 59 59



  108. row0 offset 8072   不变          MacleanZZZZZZZZZZZZZ
  109. row1 offset 8019                 a
  110. row2 offset 7935   

  111. 原row2 被夹在row0 row1之间 更新后原offset 放不下, 所以 row2被移动到 更前面的offset上。



  112. 尝试更新row1 从24字节 到 23字节 仅缩小一个字节

  113. SQL> update test_space set t1=rpad('Maclean',19,'Z') where t1='MacleanZZZZZZZZZZZZZ';

  114. 1 row updated.

  115. SQL> commit;

  116. Commit complete.



  117. tab 0, row 0, @0x1ee8
  118. tl: 23 fb: --H-FL-- lb: 0x2  cc: 1
  119. col  0: [19]  4d 61 63 6c 65 61 6e 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a
  120. tab 0, row 1, @0x1f53
  121. tl: 5 fb: --H-FL-- lb: 0x0  cc: 1
  122. col  0: [ 1]  61
  123. tab 0, row 2, @0x1eff
  124. tl: 84 fb: --H-FL-- lb: 0x0  cc: 1
  125. col  0: [80]
  126. 4d 61 63 6c 65 61 6e 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59
  127. 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59
  128. 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59
  129. 59 59 59 59 59
  130. end_of_block_dump



  131. row1 24bytes => 23bytes   offset 7912
复制代码

回复 只看该作者 道具 举报

3#
发表于 2012-5-23 20:27:09
结论 update row会使row piece 在block中的offset发生变化, oracle会尽可能把 被update的row piece 移动到 离block header较远的 但是小于 现有最小row piece offset的 空闲空间上, 这样避免出现块内的小碎片。

注意虽然offset发生了变化, 但是相关row piece的rowid是不会变的, 因为在row directory中row的位置没有变,而仅仅是offset变化; 而rowid 并不记录row piece的 offset, 而仅仅记录 其在row directory中的位置。

回复 只看该作者 道具 举报

4#
发表于 2012-5-24 08:21:22
非常清楚,理论结合实际,实验设计的真好,多谢赐教!

回复 只看该作者 道具 举报

5#
发表于 2012-5-24 08:32:35
回玩贴后又仔细看了一遍,受益匪浅,再次感谢

回复 只看该作者 道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|Archiver|Oracle数据库数据恢复、性能优化

GMT+8, 2024-12-25 13:51 , Processed in 0.052573 second(s), 24 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部
TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569