oracle bloom过滤,CSS_Oracle BLOOM过滤问题分析与解决,升入11.2.0.1遇到一个BLOOM过滤器 - phpStudy...
Oracle BLOOM過濾問題分析與解決
升入11.2.0.1遇到一個BLOOM過濾器導致的問題。
系統里面發生大量死鎖,但是這個ORA-60伴隨著另一個錯誤ORA-10387
ORA-00060: deadlock detected while waiting for resource
ORA-10387: parallel query server interrupt (normal)
通過和ORACLE SUPPORT 溝通后,認為是由bug 9124206 和 bug 8361126引起。通過設置如下參數
NAME TYPE VALUE
------------------------------------ -----------
_bloom_filter_enabled boolean FALSE
_bloom_pruning_enabled boolean FALSE
來避免這個bug。
我在metalink想查詢這兩個bug,一個是no fix, 一個是not publish(杯具)。不過通過設置這個參數,我就沒有看見過ORA-10387了,雖然ORA-60仍然很多(我OPEN了另外一個SR關于11g is more sensitive on deadlock)
那么什么是BLOOM 過濾呢,下面稍作解釋。
BLOOM算法不是ORACLE發明的新算法,它是由Burton在1970年提出的。
BLOOM過濾是一個數據結構和算法,用于判斷一個元素是否在它的集合內。
BLOOM的基本數據結構是一個數組,它的初始成員都是為0,長度為M.
【0,0,0,0,0,。。。。。。。。。。。。。。。0,0,0,0,0】
在初始化的時候,每一個要放置進去的元素,通過HASH計算出L個大小1到M的值,然后將數組的對應的成員賦值為1.一個位置,可以重復賦值。
【0,1,0,1,0,。。。。。。。。。。。。。。。0,1,0,0,1】
在進行過濾判斷的時候,過程也是一樣,通過HASH 算法將對應的位數算出來,然后去判斷是否每一位都是1,如果是,那么就說明該元素包含在當前數據集。
但是BLOOM是存在誤判的可能,這個幾率和幾個因素有關,
1. 數組的大小M
2. HASH函數的產生映射位數L(把幾個數組成員值0置為1)
3. 以及要加入數組的元素N
為什么會產生誤判?一個通俗易懂解釋,就是在M數組中加入大量的元素映射后,一部分的數組元素都變成1,那么很有可能一個并不存在于數組的中的元素,在進行判斷的時候,它的算出的映射位置恰好由幾個其它元素的映射位置占領了,這時候就會誤判它存在于這個集合。
而當M越大時,誤判就會減少。
我在網上找到一段由Christian寫的PL/SQL代碼,可以模擬這一過程,如下:
CREATE OR REPLACE PACKAGE BODY BLOOM_FILTER IS
TYPE T_BITARRAY IS TABLE OF BOOLEAN;
G_BITARRAY T_BITARRAY;
G_M???? BINARY_INTEGER;
G_K???? BINARY_INTEGER;
----------------------------------------
PROCEDURE INIT(P_M IN BINARY_INTEGER, P_N IN BINARY_INTEGER) IS
BEGIN
G_M???? := P_M;
G_BITARRAY := T_BITARRAY();
G_BITARRAY.EXTEND(P_M);
FOR I IN G_BITARRAY.FIRST .. G_BITARRAY.LAST LOOP
G_BITARRAY(I) := FALSE;
END LOOP;
G_K := CEIL(P_M / P_N * LN(2));
dbms_output.put_line('G_K='||G_K);
FOR I IN G_BITARRAY.FIRST .. G_BITARRAY.LAST LOOP
-- dbms_output.put_line(I);
IF NOT G_BITARRAY(I) THEN
NULL;
-- dbms_output.put_line('NO');
ELSE
dbms_output.put_line('YES');
END IF;
END LOOP;
END INIT;
----------------------------------------
FUNCTION ADD_VALUE(P_VALUE IN VARCHAR2) RETURN BINARY_INTEGER IS
A NUMBER;
BEGIN
DBMS_RANDOM.SEED(P_VALUE);
FOR I IN 0 .. G_K LOOP
A:=DBMS_RANDOM.VALUE(1, G_M);
dbms_output.put_line(A);
G_BITARRAY(A) := TRUE;
END LOOP;
RETURN 1;
END ADD_VALUE;
----------------------------------------
FUNCTION CONTAIN(P_VALUE IN VARCHAR2) RETURN BINARY_INTEGER IS
L_RET BINARY_INTEGER := 1;
BEGIN
DBMS_RANDOM.SEED(P_VALUE);
-- dbms_output.put_line('G_K='||G_K);
FOR I IN 0 .. G_K LOOP
IF NOT G_BITARRAY(DBMS_RANDOM.VALUE(1, G_M)) THEN
L_RET := 0;
EXIT;
END IF;
END LOOP;
RETURN L_RET;
END CONTAIN;
PROCEDURE show_nest_table IS
t NUMBER:=1;
BEGIN
FOR I IN G_BITARRAY.FIRST .. G_BITARRAY.LAST LOOP
-- dbms_output.put_line(I);
IF NOT G_BITARRAY(I) THEN
NULL;
dbms_output.put_line(I||'IS NO');
ELSE
dbms_output.put_line(I||' IS YES');
t:=t+1;
END IF;
END LOOP;
--
END;
END BLOOM_FILTER;
測試過程
創建測試表
create table t as
select dbms_random.string('u',100) As VALUE
from dual connect by level <=10000;
BLOOM數組初始化,數組大小為15000exec
bloom_filter.init(15000,1000);
加入1000個元素 (表的前1000行)
select count(bloom_filter.add_value(value))
from t
where rownum<=1000;
判斷表中數據有多少在BLOOM數組中
select count(*)
from t
where bloom_filter.contain(value)=1;
實際為1000,但結果會大于1000,說明產生了誤判。
通過增加數組的大小可以觀察,誤判逐漸消失為0.本例,大概38000的數組大小,就可以100%成功過濾1000個元素。
ORACLE在11g中支持三類類型BLOOM特性
BLOOM filter
BLOOM partition pruning
Support result cache
但是不幸的是,由于bug,我們已經關閉前兩種相關閱讀:
Javascript 瀏覽器事件小結
CSS元素的層疊與z-index設置
外部表在Oracle數據庫中使用心得
JSP模板應用指南(上)
用緩沖技術提高JSP應用的性能和穩定性
用stack變量優化Java代碼
關于CSS網頁布局id與class的命名
影響Oracle中文顯示的字符集分析
HTML5 CSS3新的WEB標準和瀏覽器支持
Asp備份與恢復SQL Server數據庫
HTML5中div§ion&article之間的區別
Ajax獲取頁面被緩存的解決方案
帝國ECMS教程:上一篇下一篇自定義綜合代碼
PHP 中文亂碼解決辦法總結分析
總結
以上是生活随笔為你收集整理的oracle bloom过滤,CSS_Oracle BLOOM过滤问题分析与解决,升入11.2.0.1遇到一个BLOOM过滤器 - phpStudy...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php ucword,ThinkPHP3
- 下一篇: InnoDB原理篇:如何用好索引