ITPub博客

首页 > Linux操作系统 > Linux操作系统 > online rebuild发生的问题[转载]

online rebuild发生的问题[转载]

原创 Linux操作系统 作者:qingcheng_yuan 时间:2011-09-07 14:58:20 0 删除 编辑

http://www.hellodb.net/2010/01/online_rebuil.html

朋友遇到一个问题,当建立一个包含varchar2(4000)的索引时,直接创建没有问题,但是如果加上online子句,则报错:

ORA-00604: error occurred at recursive SQL level 1
ORA-01450: maximum key length (3215) exceeded

这里实际上包含了两个问题:

1.索引的key到底可以有多大?因为索引的key是不可以跨越block的,所以最直接的决定因素是block size,Oracle的文档给出了一个计算公式:

DB_BLOCK_SIZE:                  Maximum Index Key Length:
==============                  =========================

2K  (2048)                       758  Bytes
4K  (4096)                       1578 Bytes
8K  (8192)                       3218 Bytes
16K (16384)                      6498 Bytes

文档中说:每个index leaf block至少有两行记录,考虑block header,PCTFREE,INITRANS等因素,每个index key最大可以为block size的40%。但是我测试了一下(8K block size),发现并不是如此。

create table test(id varchar2(4000),id2 varchar2(3000));
create index test_ind on test(id,id2);
ORA-01450: maximum key length (6398) exceeded

最大的长度是6398,而不是文档中提到的3218,后来我把block dump出来,发现每个index leaf block中只有一行,而不是文档中所说的至少有两行,这样index key的最大值就自然变大了,大约为block size的80%。为什么与文档上不一致,应该是版本的问题,文档描述的是在9i之前的情况,而9i之后Oracle作了改进(没有8i的环境,没法证实)。

2.为什么online无法创建,而直接创建没有问题呢?

因为online创建的过程中会生成一个中间表,用来记录创建过程中的变化,而这个表是IOT表。经过测试,发现IOT表的限制比较严格,8k的block size,最大长度只能有3215,所以普通创建可以成功,而online创建则不行,关键还在背后的IOT表上。

怎么解决这个问题,Oracle的官方说法是加大block size,但是对于IOT表,我们发现加大block size并没有太大作用,最大长度也只有3800。看来,对于INDEX每个block可以只存放一条,而IOT比较特殊,每个block需要至少存放两条记录。简单点说,IOT的限制比普通INDEX更严格一些,至于为什么,我想也许没什么特别的原因吧,也许只是版本改进过程中的代码问题。

我很奇怪,怎么会在varchar2(4000)的字段上建索引呢?一问才知道,原来这个字段实际内容并不长,但是当时设计时,可能是为了方便,直接设计成最大值了,才导致现在的问题。现在只能想办法,重新建一个适当长度的字段,把内容拷贝过去,然后再建立索引。

–EOF–

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

请登录后发表评论 登录
全部评论

注册时间:2009-09-24

  • 博文量
    12
  • 访问量
    31936