BITMAP索引異常增大
在一個資料庫中發現了一個異常增大的物件,經檢查改物件為BITMAP索引。
在資料庫中執行下面的指令碼,發現了一個異常增大的物件:
SQL> SELECT SEGMENT_NAME, SEGMENT_TYPE, SUM(BYTES)/1024/1024/1024 G
2 FROM USER_SEGMENTS
3 GROUP BY SEGMENT_NAME, SEGMENT_TYPE
4 HAVING SUM(BYTES)/1024/1024/1024 > 15;
SEGMENT_NAME SEGMENT_TYPE G
------------------------------ ------------------ ----------
TU_ORD_ORDER_ZJ_K_CODE INDEX 16.7539215
檢查該物件的詳細資訊:
SQL> SELECT INDEX_NAME, INDEX_TYPE FROM USER_INDEXES
2 WHERE INDEX_NAME = 'TU_ORD_ORDER_ZJ_K_CODE';
INDEX_NAME INDEX_TYPE
------------------------------ ---------------------------
TU_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,
2 p_segment_type in varchar2 default 'TABLE',
3 p_segment_owner in varchar2 default user,
4 p_partition_name in varchar2 default '') as
5 v_unformatted_blocks number;
6 v_unformatted_bytes number;
7 v_fs1_blocks number;
8 v_fs1_bytes number;
9 v_fs2_blocks number;
10 v_fs2_bytes number;
11 v_fs3_blocks number;
12 v_fs3_bytes number;
13 v_fs4_blocks number;
14 v_fs4_bytes number;
15 v_full_blocks number;
16 v_full_bytes number;
17 begin
18 dbms_space.space_usage(upper(p_segment_owner), upper(p_segment_name), upper(p_segment_type), v_unformatted_blocks,
19 v_unformatted_bytes, v_fs1_blocks, v_fs1_bytes, v_fs2_blocks, v_fs2_bytes, v_fs3_blocks, v_fs3_bytes,
20 v_fs4_blocks, v_fs4_bytes, v_full_blocks, v_full_bytes, upper(p_partition_name));
21
22 dbms_output.put_line('unformatted_blocks is ' || v_unformatted_blocks);
23 dbms_output.put_line('unformatted_bytes is ' || v_unformatted_bytes);
24 dbms_output.put_line('fs1_blocks is ' || v_fs1_blocks);
25 dbms_output.put_line('fs1_bytes is ' || v_fs1_bytes);
26 dbms_output.put_line('fs2_blocks is ' || v_fs2_blocks);
27 dbms_output.put_line('fs2_bytes is ' || v_fs2_bytes);
28 dbms_output.put_line('fs3_blocks is ' || v_fs3_blocks);
29 dbms_output.put_line('fs3_bytes is ' || v_fs3_bytes);
30 dbms_output.put_line('fs4_blocks is ' || v_fs4_blocks);
31 dbms_output.put_line('fs4_bytes is ' || v_fs4_bytes);
32 dbms_output.put_line('full_blocks is ' || v_full_blocks);
33 dbms_output.put_line('full_bytes is ' || v_full_bytes);
34 end;
35 /
Procedure created.
SQL> SET SERVEROUT ON SIZE 10000
SQL> EXEC P_SPACE_USAGE('TU_ORD_ORDER_ZJ_K_CODE', 'INDEX', 'NDMAIN')
unformatted_blocks is 2038268
unformatted_bytes is 16697491456
fs1_blocks is 0
fs1_bytes is 0
fs2_blocks is 139652
fs2_bytes is 1144029184
fs3_blocks is 0
fs3_bytes is 0
fs4_blocks is 0
fs4_bytes is 0
full_blocks is 13365
full_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
2 FROM DBA_TABLESPACES
3 WHERE TABLESPACE_NAME = 'USERS';
TABLESPACE_NAME SEGMEN
------------------------------ ------
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
2 FOR I IN REVERSE 1..1000 LOOP
3 UPDATE T SET BITMAP_COL = 1
4 WHERE BITMAP_COL = 0 AND ID = I;
5 END LOOP;
6 END;
7 /
PL/SQL 過程已成功完成。
SQL> SET SERVEROUT ON SIZE 1000000
SQL> EXEC P_SPACE_USAGE('IND_B_T_BIT', 'INDEX')
unformatted_blocks is 93536
unformatted_bytes is 766246912
fs1_blocks is 0
fs1_bytes is 0
fs2_blocks is 8211
fs2_bytes is 67264512
fs3_blocks is 0
fs3_bytes is 0
fs4_blocks is 0
fs4_bytes is 0
full_blocks is 18
full_bytes is 147456
PL/SQL 過程已成功完成。
這個結果和這裡碰到的問題幾乎完全一致,只不過這個例子是人為構造bug的產生,而資料庫中則是由於正常修改在某些情況下觸發了這個bug,檢查當前的表空間資訊:
SQL> SELECT INDEX_NAME, TABLESPACE_NAME FROM USER_INDEXES
2 WHERE INDEX_NAME = 'TU_ORD_ORDER_ZJ_K_CODE';
INDEX_NAME TABLESPACE_NAME
------------------------------ ------------------------------
TU_ORD_ORDER_ZJ_K_CODE INDX
SQL> SELECT SEGMENT_SPACE_MANAGEMENT FROM USER_TABLESPACES
2 WHERE TABLESPACE_NAME = 'INDX';
SEGMEN
------
AUTO
這個Bug在10.1.0.2被修正,對於9.2.0.2以上的版本,可以直接下載編號為2915226的patch來解決這個問題。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-244198/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- windows C 盤大小異常增大並解決記錄Windows
- BITMAP索引的INLIST ITERATOR與BITMAP OR索引
- 乾貨:Bitmap 複用時的一個異常
- 點陣圖索引(Bitmap Index)——索引共用索引Index
- [轉]:bitmap索引和B*tree索引分析索引
- 索引組織表上建立BITMAP索引(三)索引
- 索引組織表上建立BITMAP索引(二)索引
- 索引組織表上建立BITMAP索引(一)索引
- oracle 點陣圖索引(bitmap index)Oracle索引Index
- 點陣圖索引:原理(BitMap index)索引Index
- 點陣圖索引(bitmap-index)索引Index
- 物化檢視上使用bitmap索引索引
- 【Bitmap Index】B-Tree索引與Bitmap點陣圖索引的鎖代價比較研究Index索引
- bitmap index點陣圖索引系列(一)Index索引
- 點陣圖索引(Bitmap Index)——從B*樹索引到點陣圖索引索引Index
- 異常篇——異常處理
- 異常和異常呼叫鏈
- 【索引】Bitmap點陣圖索引與普通的B-Tree索引鎖的比較索引
- Java 異常(二) 自定義異常Java
- Java checked異常和unchecked異常。Java
- 異常-編譯期異常和執行期異常的區別編譯
- 分割槽表的bitmap索引不能是global的索引
- 異常-throws的方式處理異常
- 異常處理與異常函式函式
- jmu-Java-06異常-01-常見異常Java
- hibernate異常之--count查詢異常
- Java 異常表與異常處理原理Java
- restframework 異常處理及自定義異常RESTFramework
- 點陣圖索引(Bitmap Index)——點陣圖索引與資料DML鎖定索引Index
- zt_深入理解bitmap index點陣圖索引Index索引
- oracle 異常Oracle
- OutOfMemoryError異常Error
- Java異常Java
- 異常(Exception)Exception
- Java 異常Java
- 異常JavaJava
- 【java】異常Java
- java 異常Java