楼主: 红叶DBA

[讨论] 关于数据库 Block 存储细节问题的讨论

[复制链接]
论坛徽章:
4
鲜花蛋
日期:2011-07-21 16:06:54双黄蛋
日期:2011-09-02 20:36:17ITPUB十周年纪念徽章
日期:2011-11-01 16:26:29奥运会纪念徽章:射箭
日期:2012-07-26 19:04:19
11#
发表于 2011-7-10 11:37 | 只看该作者
原帖由 红叶DBA 于 2011-7-10 10:54 发表


有人认为数据块中所有的记录都是紧密排列的,也就是说一行接一行的存储!

但是我表示怀疑,因为这样的话,那么删除一行,或者是一行的数据长度变小的时候,那不是得整个块中其后面的数据都得向前移动?

事实上,当删除一个块中的某一行时,此数据行的位置还在,并没有被后面的行覆盖,在dump 文件中显示为:
tab 0, row 4, @0x1d69
tl: 2 fb: --HDFL-- lb: 0x2   -- 其中D标识,预示着这是一个被删除的行。

而且被删除的行,也不是马上就被重用的,也就是说,你后面再插入一个新行的话,其实并不是利用这个删除行所释放的空间,

而是从 extent 中另外寻找空间,这其中 关于位图块 空间的分配问题,我还不懂 。

希望高手解惑 !



hi,红叶
      我不知道你的实验中的,是index block还是table block。
      “那么删除一行,或者是一行的数据长度变小的时候,那不是得整个块中其后面的数据都得向前移动”,Oracle肯定是不会这样做的。
      假设一个场景,如果有一个varchar(200)的字段,你只用了其中2位数据,余下的198位,是会保留的,这个时候,如果做update操作,新的值比200小而没有操作pctfree,剩余的空间会少些,如果新的值导致超过了pctfree参数,会导致row migration现象。

      “事实上,当删除一个块中的某一行时,此数据行的位置还在,并没有被后面的行覆盖,在dump 文件中显示为:
tab 0, row 4, @0x1d69
tl: 2 fb: --HDFL-- lb: 0x2   -- 其中D标识,预示着这是一个被删除的行。

而且被删除的行,也不是马上就被重用的,也就是说,你后面再插入一个新行的话,其实并不是利用这个删除行所释放的空间”

        我不知道你实验时,是否有做commit操作,Oracle为了实现“read consistency”,在同一个transaction中,不会利用重复利用被delete的row的空间的。
        详细可以参见我做的实验http://www.itpub.net/thread-1425119-1-1.html。实验中,我没有commit,导致uniform size和autolocate的表空间,在碎片化上,几乎没有什么区别。
        
        参考链接    asktom  http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1396006300346456969
                        asktom  http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:749748700346764790

使用道具 举报

回复
论坛徽章:
13
数据库板块每日发贴之星
日期:2010-08-24 01:01:012012新春纪念徽章
日期:2012-01-04 11:57:13ITPUB十周年纪念徽章
日期:2011-11-01 16:25:51数据库板块每日发贴之星
日期:2011-07-11 01:01:01ITPUB伯乐
日期:2011-06-16 10:11:39ITPUB季度 技术新星
日期:2011-01-17 11:30:46授权会员
日期:2010-12-28 19:29:32ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51数据库板块每日发贴之星
日期:2010-09-07 01:01:01数据库板块每日发贴之星
日期:2010-08-28 01:01:01
12#
 楼主| 发表于 2011-7-10 11:47 | 只看该作者
commit 这种事情怎么可能会忘记?

你这里的碎片化 和我讨论的这个碎片化不是同一个概念。

uniform 和 autoallocate 的区别在区间大小的分配上,这时候的碎片都是块级别以上的了,甚至是 extent 级别的。

而我这里所说的列是否紧密,则表示的是块内部的碎片化问题。

使用道具 举报

回复
论坛徽章:
13
数据库板块每日发贴之星
日期:2010-08-24 01:01:012012新春纪念徽章
日期:2012-01-04 11:57:13ITPUB十周年纪念徽章
日期:2011-11-01 16:25:51数据库板块每日发贴之星
日期:2011-07-11 01:01:01ITPUB伯乐
日期:2011-06-16 10:11:39ITPUB季度 技术新星
日期:2011-01-17 11:30:46授权会员
日期:2010-12-28 19:29:32ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51数据库板块每日发贴之星
日期:2010-09-07 01:01:01数据库板块每日发贴之星
日期:2010-08-28 01:01:01
13#
 楼主| 发表于 2011-7-10 11:51 | 只看该作者
原帖由 freas 于 2011-7-10 11:37 发表



hi,红叶

      假设一个场景,如果有一个varchar(200)的字段,你只用了其中2位数据,余下的198位,是会保留的,这个时候,如果做update操作,新的值比200小而没有操作pctfree,剩余的空间会少些,如果新的值导致超过了pctfree参数,会导致row migration现象。



照你这样的理解 varchar(200) 就算使用了2,也需要保留198,那和 char(200) 又有什么区别呢?这样的结果必然是导致块中保留了很多空间,照成大量的空间浪费了。

而且如果能保留这个 198 的空间,那还要 pctfree 干嘛呢?毕竟 pctfree 的空间就是留给 update 的嘛 。

使用道具 举报

回复
论坛徽章:
4
鲜花蛋
日期:2011-07-21 16:06:54双黄蛋
日期:2011-09-02 20:36:17ITPUB十周年纪念徽章
日期:2011-11-01 16:26:29奥运会纪念徽章:射箭
日期:2012-07-26 19:04:19
14#
发表于 2011-7-10 12:10 | 只看该作者
原帖由 红叶DBA 于 2011-7-10 11:51 发表


照你这样的理解 varchar(200) 就算使用了2,也需要保留198,那和 char(200) 又有什么区别呢?这样的结果必然是导致块中保留了很多空间,照成大量的空间浪费了。

而且如果能保留这个 198 的空间,那还要 pctfree 干嘛呢?毕竟 pctfree 的空间就是留给 update 的嘛 。




照你这样的理解 varchar(200) 就算使用了2,也需要保留198,那和 char(200) 又有什么区别呢?”
这里出现了笔误,把char想成了varchar了,误以为varchar2之前有个varchar是定长的。


而且如果能保留这个 198 的空间,那还要 pctfree 干嘛呢?毕竟 pctfree 的空间就是留给 update 的嘛 。

如果是char类型的,198是用空格来填补的。

这个时候,如果对该字段进行update操作,而且update后的值比原值长,那么,是会用198中的空间的。

对varchar2经常update的话,更能容易造成row migration现象。

参考链接

http://blog.csdn.net/LisaChen518/article/details/3245212

[ 本帖最后由 freas 于 2011-7-10 12:19 编辑 ]

使用道具 举报

回复
论坛徽章:
4
鲜花蛋
日期:2011-07-21 16:06:54双黄蛋
日期:2011-09-02 20:36:17ITPUB十周年纪念徽章
日期:2011-11-01 16:26:29奥运会纪念徽章:射箭
日期:2012-07-26 19:04:19
15#
发表于 2011-7-10 12:47 | 只看该作者
原帖由 红叶DBA 于 2011-7-10 11:47 发表
commit 这种事情怎么可能会忘记?

你这里的碎片化 和我讨论的这个碎片化不是同一个概念。

uniform 和 autoallocate 的区别在区间大小的分配上,这时候的碎片都是块级别以上的了,甚至是 extent 级别的。

而我这里所说的列是否紧密,则表示的是块内部的碎片化问题。



是有点儿跑题了。


以下是关于你的问题的官方解释:

“An example might better define how to store rows in blocks. For insert only, start at
the "bottom" of the block and move up. For an update, try to reuse the space. If that
doesn't work treat it almost like a delete followed by an insert. On insert, try to reuse
the first free slot in the row directory. Then try to grab space in the free area. If there
isn't enough contiguous space in the free area, call kdbcps() to compress the block.
For example, assume that you initially have rows 1, 2, 3, 4, 5 of 10 bytes each. The
offsets of the rows will actually be 5, 4, 3, 2, 1 because of the “bottom/up” algorithm.
Delete rows 2 and 4, then insert a new row with 20 bytes. It is very likely that slot 2 of
the row directory will be used, but the actual space used will be above row 5 (whether
compression happens or not).
So, if you sort the rows by row offset, the new offset
order will look like 2, 5, 3, 1 and becoming more random as you have more DML
activity in the block.”

更为具体和详细的内幕,需要自己看了,这个,三两句话可能真的说不清楚。

Reference 《dsi402e-d12865》   Chapter 3 Page-17

使用道具 举报

回复
论坛徽章:
86
2015中国数据库技术大会纪念徽章
日期:2015-04-24 16:04:24马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11优秀写手
日期:2013-12-18 09:29:11日产
日期:2013-10-17 08:44:39马自达
日期:2013-08-26 16:28:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-23 16:55:51马上有房
日期:2014-02-19 11:55:14
16#
发表于 2011-7-11 12:31 | 只看该作者
原帖由 红叶DBA 于 2011-7-9 23:35 发表
3、正常的 Data Block 中,行数据是否是紧密连接的么?如果删除一些块中间位置的行,那么块中的数据还是紧密的么?


初始化状态是紧密连接的。
如果发生删除,则仅仅是在row header中加删除标志,如果发生更新,更新前和更新后的字节相同,则直接修改字段值,如果字节不同,则在快内重新分配空间,并修改指向偏移量,如快内没有可用空间,则进行行迁移

使用道具 举报

回复
论坛徽章:
47
蒙奇·D·路飞
日期:2017-03-27 08:04:23马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11一汽
日期:2013-09-01 20:46:27复活蛋
日期:2013-03-13 07:55:232013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:322012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20
17#
发表于 2011-7-11 23:22 | 只看该作者
原帖由 freas 于 2011-7-9 19:42 发表


hi,Yong Huang

      I have different opinion.

      Myth: Space Is Never Reused in an Index
This is a myth that I would like to dispel once and for all: space is reused in an index. The myth goes like
this: you have a table, T, in which there is a column, X. At some point, you put the value X=5 in the table.
Later you delete it. The myth is that the space used by X=5 will not be reused unless you put X=5 back into
the index later. The myth states that once an index slot is used, it will be there forever and can be reused
only by the same value. A corollary to this is the myth that free space is never returned to the index
structure, and a block will never be reused. Again, this is simply not true.

      And tom did a test to prove that The Myth is not true.
                                                                                                                          p485  Tomas Kyte

      freas
      junior


I think this is a mis-reading of Tom's writing, which I read before. Note my wording "Space for an index entry". Tom is dismissing the myth about space, *as an entire block*, for that index entry. I wish Tom had pointed it out clearly, and I should've been more specific.

The "subtle" difference is not hard to understand. One block (usually) can contain many index entries. What I said is that if index key 5 is deleted, the space used by value 5, perhaps a few bytes, is not re-used unless 5 is put back. Saying the entire block that used to have 5 will no longer accept new values is of course wrong. If you read Tom's book, the example following his myth dismissal, you'll see that he's talking about the *block* can still be re-used. Unfortunately, in this paragraph here, he used the word "slot". But read his demo anyway.

A good test would be, make sure one index entry takes one whole block, perhaps by setting pctfree very high.

Yong Huang

使用道具 举报

回复
论坛徽章:
47
蒙奇·D·路飞
日期:2017-03-27 08:04:23马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11一汽
日期:2013-09-01 20:46:27复活蛋
日期:2013-03-13 07:55:232013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:322012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20
18#
发表于 2011-7-11 23:28 | 只看该作者
> 2、看 http://ms.itpub.net/thread-1447324-1-1.html 中的 3#(zergduan版主),我发现这样一句话:
> In a nonunique index, you will find that the data is sorted first by index key values (in the order of the index key) and then by rowid ascending.
> 这不是说的索引中先以 key 排序(这是必须的),然后以 ROWID 排序的么?

You all are right. I read that discussion before but I forgot. Rowid serves as part of the non-unique index key. It will be sorted (if the index part in front of it is the same).

Yong Huang

使用道具 举报

回复
论坛徽章:
4
鲜花蛋
日期:2011-07-21 16:06:54双黄蛋
日期:2011-09-02 20:36:17ITPUB十周年纪念徽章
日期:2011-11-01 16:26:29奥运会纪念徽章:射箭
日期:2012-07-26 19:04:19
19#
发表于 2011-7-12 12:26 | 只看该作者
原帖由 Yong Huang 于 2011-7-11 23:22 发表


I think this is a mis-reading of Tom's writing, which I read before. Note my wording "Space for an index entry". Tom is dismissing the myth about space, *as an entire block*, for that index entry. I wish Tom had pointed it out clearly, and I should've been more specific.

The "subtle" difference is not hard to understand. One block (usually) can contain many index entries. What I said is that if index key 5 is deleted, the space used by value 5, perhaps a few bytes, is not re-used unless 5 is put back. Saying the entire block that used to have 5 will no longer accept new values is of course wrong. If you read Tom's book, the example following his myth dismissal, you'll see that he's talking about the *block* can still be re-used. Unfortunately, in this paragraph here, he used the word "slot". But read his demo anyway.

A good test would be, make sure one index entry takes one whole block, perhaps by setting pctfree very high.

Yong Huang


hi,Yong Huang

"Note my wording "Space for an index entry". Tom is dismissing the myth about space, *as an entire block*, for that index entry. I wish Tom had pointed it out clearly, and I should've been more specific."

There're two mythes in tom's book:

myth one:
        The myth states that once an index slot(I think it's not lapsus calami) is used, it will be there forever and can be reused only by the same value.

myth two:
         free space is never returned to the index structure, and a block will never be reused.(which is the corollary of myth one)

         (I think)Tom thinks that his demo prove that myth two is wrong,so,myth one is indirectly proved to be wrong.

[ 本帖最后由 freas 于 2011-7-12 15:58 编辑 ]

使用道具 举报

回复
论坛徽章:
4
鲜花蛋
日期:2011-07-21 16:06:54双黄蛋
日期:2011-09-02 20:36:17ITPUB十周年纪念徽章
日期:2011-11-01 16:26:29奥运会纪念徽章:射箭
日期:2012-07-26 19:04:19
20#
发表于 2011-7-12 12:29 | 只看该作者
SQL> create table t (x int);

表已创建。

SQL> drop index ind_freas;

索引已删除。

SQL> create index ind_freas on t(x) pctfree 99;                    ——>pctfree is very highbut to indexespctfree only works when when
                                                                                                          the leaf block is created.
索引已创建。

SQL> insert into t values(1);

已创建 1 行。

SQL> insert into t values(2);

已创建 1 行。

SQL> insert into t values(9999999999);

已创建 1 行。

SQL> analyze index ind_freas validate structure;

索引已分析

SQL> select lf_blks,br_blks,btree_space from index_stats;


LF_BLKS   BR_BLKS   BTREE_SPACE

----------     ----------        -----------
1                  
0                 8000                                       
——>leaf block is only 1

SQL> begin
2  for i in 2..999999

3  loop

4  delete from t where x=i;

5  commit;

6  insert into t values(i+1);
7  commit;

8  end loop;

9  end;

10  /

PL/SQL 过程已成功完成。                                              ——>it take's long.

SQL> select lf_blks,br_blks,btree_space from index_stats;


LF_BLKS  BR_BLKS  BTREE_SPACE

----------   ----------    -----------

1                    0          8000                                                   
——>leaf block remains only 1
                                                                                             ——>it implies that the index slots are reused.

related links
     asktom   http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2424495760219

[ 本帖最后由 freas 于 2011-7-13 08:38 编辑 ]

使用道具 举报

回复

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

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表