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