我申请这个blog是为了督促自己,把自己平时的一些想法和思考结果保留下来。 本博客所有内容均为原创,如有转载请注明作者和出处

BITMAP索引异常增大

上一篇 / 下一篇  2008-04-19 23:00:30 / 个人分类:Bug

在一个数据库中发现了一个异常增大的对象,经检查改对象为BITMAP索引。

 

 

在数据库中执行下面的脚本,发现了一个异常增大的对象:

SQL> SELECT SEGMENT_NAME, SEGMENT_TYPE, SUM(BYTES)/1024/1024/1024 G
J[Fho*U+_0  2  FROM USER_SEGMENTSITPUB个人空间(s!E)vR,x;o2]
  3  GROUP BY SEGMENT_NAME, SEGMENT_TYPE
1vJ9L:K'B PJ| O0  4  HAVING SUM(BYTES)/1024/1024/1024 > 15;

SEGMENT_NAME                   SEGMENT_TYPE                G
9IL Z\9h"tZ |Vy0l0------------------------------ ------------------ ----------ITPUB个人空间S a#O+kE eqd
TU_ORD_ORDER_ZJ_K_CODE         INDEX              16.7539215

检查该对象的详细信息:

SQL> SELECT INDEX_NAME, INDEX_TYPE FROM USER_INDEXES     
NSDL*T wd*v0  2  WHERE INDEX_NAME = 'TU_ORD_ORDER_ZJ_K_CODE';

INDEX_NAME                     INDEX_TYPEITPUB个人空间5U]&Y&]6DN8F$aP
------------------------------ ---------------------------
"mbC9AQ0TU_ORD_ORDER_ZJ_K_CODE         FUNCTION-BASED BITMAP

这个对象是一个基于函数的BITMAP索引。一般来说,BITMAP索引的大小要远远小于普通索引,而这里索引的大小达到了16G,远远超过表本身的大小,这里肯定存在问题。通过对DBMS_SPACE包中SPACE_USAGE过程的封装,检查这个对象的空间使用情况:

SQL> create or replace procedure p_space_usage (p_segment_name in varchar2,ITPUB个人空间"rWe9QjK2r
  2     p_segment_type in varchar2 default 'TABLE',
eg)dx#AC"x@C0  3     p_segment_owner in varchar2 default user,ITPUB个人空间_JwF\:|V
  4     p_partition_name in varchar2 default '') asITPUB个人空间M!c rW#K
  5     v_unformatted_blocks number;ITPUB个人空间v ^OrI
  6     v_unformatted_bytes number;
t$r!lL5X1Z1Z"G0  7     v_fs1_blocks number;ITPUB个人空间c7e#q-Ef ~
  8     v_fs1_bytes number;ITPUB个人空间l/}M VX
  9     v_fs2_blocks number;
RUU6Da#?0 10     v_fs2_bytes number;ITPUB个人空间 x4z`/U;F,\&~
 11     v_fs3_blocks number;
&t$O_ X*K"j3@0 12     v_fs3_bytes number;ITPUB个人空间*jN,{/j7A
 13     v_fs4_blocks number;ITPUB个人空间;JD!W+xWKk
 14     v_fs4_bytes number;ITPUB个人空间:@9N A qYHu?)om9J.g
 15     v_full_blocks number;ITPUB个人空间g.Sv7Z6sMM o]
 16     v_full_bytes number;
6~-Y4CK+c*N0 17  begin
0s7V1|yA9}T0 18     dbms_space.space_usage(upper(p_segment_owner), upper(p_segment_name), upper(p_segment_type), v_unformatted_blocks,
m2kNTC0 19             v_unformatted_bytes, v_fs1_blocks, v_fs1_bytes, v_fs2_blocks, v_fs2_bytes, v_fs3_blocks, v_fs3_bytes,
#d WO:q6u9x {%^+AH2C5]"z0 20             v_fs4_blocks, v_fs4_bytes, v_full_blocks, v_full_bytes, upper(p_partition_name));
A(B T+AC$\&iy"@0 21    
(H3X#yC%ooK0 22     dbms_output.put_line('unformatted_blocks is ' || v_unformatted_blocks);ITPUB个人空间sS[NQ-U
 23     dbms_output.put_line('unformatted_bytes is ' || v_unformatted_bytes);ITPUB个人空间 s1xw?'{iE}
 24     dbms_output.put_line('fs1_blocks is ' || v_fs1_blocks);
A-?5H G(A0`0 25     dbms_output.put_line('fs1_bytes is ' || v_fs1_bytes);ITPUB个人空间\m }%@] F$j Rv
 26     dbms_output.put_line('fs2_blocks is ' || v_fs2_blocks);
4F+GY/T5Rh!q0 27     dbms_output.put_line('fs2_bytes is ' || v_fs2_bytes);ITPUB个人空间%fq r_3}!a AO
 28     dbms_output.put_line('fs3_blocks is ' || v_fs3_blocks);
$Jf+y+z.h"N0 29     dbms_output.put_line('fs3_bytes is ' || v_fs3_bytes);
#?4C2p7C+X*m~0 30     dbms_output.put_line('fs4_blocks is ' || v_fs4_blocks);ITPUB个人空间Shd B2d:tO%SD
 31     dbms_output.put_line('fs4_bytes is ' || v_fs4_bytes);
#j l b6Pa0 32     dbms_output.put_line('full_blocks is ' || v_full_blocks);
&C6tX8_S0 33     dbms_output.put_line('full_bytes is ' || v_full_bytes);ITPUB个人空间 z*iJ.W,X
 34  end;ITPUB个人空间3eu&G"GC d B:}
 35  /

Procedure created.

SQL> SET SERVEROUT ON SIZE 10000ITPUB个人空间 @8P#VuZI#JF
SQL> EXEC P_SPACE_USAGE('TU_ORD_ORDER_ZJ_K_CODE', 'INDEX', 'NDMAIN')
+x f4VUDeJ0unformatted_blocks is 2038268ITPUB个人空间;vj-t @\o:c X&R I%{
unformatted_bytes is 16697491456ITPUB个人空间Q7V mK:o7tn/^C
fs1_blocks is 0
b;is \$F[B t^&C)n*j0fs1_bytes is 0ITPUB个人空间:f0[o!u)FbN!D
fs2_blocks is 139652ITPUB个人空间6l[!AQaj
fs2_bytes is 1144029184ITPUB个人空间 IYk-k'G4DQ)k&f
fs3_blocks is 0
#O)P s O]5D#Fh0fs3_bytes is 0
HM^"NNbI [ \*Y2\0fs4_blocks is 0
j5U#H9f*j`0fs4_bytes is 0
W6WF8k6R WneH7D0full_blocks is 13365
Ag2b|oD}7I|0full_bytes is 109486080

PL/SQL procedure successfully completed.

问题已经很显然了,这个基于函数的BITMAP索引包含了大量的unformatted blocks,造成大量空间的浪费,而实际上索引所需要的空间并没有这么大。

检查METALINK,发现Oracle处理ASSM表空间的BITMAP索引存在空间浪费的bug,详细bug描述参考:Bug No. 2915226

Oracle给出了一个例子来重现这个bug

SQL> SELECT TABLESPACE_NAME, SEGMENT_SPACE_MANAGEMENT         ITPUB个人空间*C_ l*n)PdH
  2  FROM DBA_TABLESPACES
)e:m#?IT]0  3  WHERE TABLESPACE_NAME = 'USERS';

TABLESPACE_NAME                SEGMEN
+MktK,x&g0------------------------------ ------ITPUB个人空间:{0C {8La,z4F*w:MF }
USERS                          AUTO

SQL> CREATE TABLE T (ID NUMBER NOT NULL, BITMAP_COL NUMBER NOT NULL);

表已创建。

SQL> INSERT INTO T SELECT ROWNUM, MOD(ROWNUM, 2) FROM DBA_OBJECTS;

已创建31016行。

SQL> CREATE BITMAP INDEX IND_B_T_BIT ON T(BITMAP_COL) TABLESPACE USERS;

索引已创建。

SQL> BEGIN
QQEe!eO-m0  2  FOR I IN REVERSE 1..1000 LOOP
Vam d%P"C[H]0  3  UPDATE T SET BITMAP_COL = 1ITPUB个人空间hN ap-\4j } e h&{ d
  4  WHERE BITMAP_COL = 0  AND ID = I;
G9Q_%r7U;Z#_H#e2A0  5  END LOOP;
iD;Eh `cMR0  6  END;ITPUB个人空间,},vvB!ZN;WNT
  7  /

PL/SQL过程已成功完成。

SQL> SET SERVEROUT ON SIZE 1000000
\.TEb&j7x${ Bh0SQL> EXEC P_SPACE_USAGE('IND_B_T_BIT', 'INDEX')ITPUB个人空间k(lU;E%~
unformatted_blocks is 93536ITPUB个人空间Vl Zz_@*]S]
unformatted_bytes is 766246912ITPUB个人空间OG'p+R L&{{
fs1_blocks is 0
a$eZ9\#Pc Q1nD0fs1_bytes is 0
vF2]E:i,}6q(D)I0fs2_blocks is 8211
{ @%n*K RQ6g0fs2_bytes is 67264512
l"{d*X@5v2^0fs3_blocks is 0ITPUB个人空间(xH sqn|.c A
fs3_bytes is 0ITPUB个人空间oJo dG7n(\
fs4_blocks is 0ITPUB个人空间6pX(Hq1HP/ZW-b?
fs4_bytes is 0ITPUB个人空间6S6QNW @*C-NgC _/m4l e'm
full_blocks is 18
(cBn1q \)SFE0full_bytes is 147456

PL/SQL过程已成功完成。

这个结果和这里碰到的问题几乎完全一致,只不过这个例子是人为构造bug的产生,而数据库中则是由于正常修改在某些情况下触发了这个bug,检查当前的表空间信息:

SQL> SELECT INDEX_NAME, TABLESPACE_NAME FROM USER_INDEXES ITPUB个人空间Bjj`,Li
  2  WHERE INDEX_NAME = 'TU_ORD_ORDER_ZJ_K_CODE';

INDEX_NAME                     TABLESPACE_NAMEITPUB个人空间h8m"e7b4ZC
------------------------------ ------------------------------ITPUB个人空间Ly,A9C)gF3fF*E
TU_ORD_ORDER_ZJ_K_CODE         INDX

SQL> SELECT SEGMENT_SPACE_MANAGEMENT FROM USER_TABLESPACES  ITPUB个人空间8{qG!pW
  2  WHERE TABLESPACE_NAME = 'INDX';

SEGMENITPUB个人空间6f3m2X r(m)TQ#nI)QzQ
------
I;YkRWT Hc0AUTO

这个Bug10.1.0.2被修正,对于9.2.0.2以上的版本,可以直接下载编号为2915226patch来解决这个问题。

 


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar