找出索引鍵值出錯的數據ID

這個禮拜輪到我做production support。今天碰到的一個問題是:X Pool的搜索節點crash!

 

 

通過分析core file和access log,我們定位到killing query。發現當輸入關鍵字符合特定pattern的時候,search node就會crash。

 

根本原因是data issue。即:處理代碼認爲根本不可能出現某類數據,但是不幸出現了,導致代碼執行異常。處理production issue時首先要考慮的問題就是如何讓production環境儘快恢復運行,於是我們的任務就是找出索引文件中出問題的X數據的ID,爲其重建索引。

 

問題轉化爲:找出索引文件中索引鍵值符合給定pattern的數據ID。

 

搜索引擎中每個field的屬性至少有兩類:store還是index,

 

store表示這個值要保存,但是不一定爲這個值建索引;

index表示爲這個值建索引,但不一定能夠顯示(只有保存的Field纔可以顯示)。

 

有興趣的同學可以看一下《Lucene 2.0+Heritrix 開發自己的搜索引擎》這本書,裏面對存儲,索引和分詞有詳細的解釋。

 

我們的難點是:我們沒有辦法利用搜索節點來找出擁有符合特定模式屬性的ID,因爲一送這樣的query程序就crash了。而且我們不一定看得見某個數據是不是含有一個索引值符合給定的pattern,因爲這個索引值很有可能沒有store屬性。雖然數據庫中保存着原始數據,但是一個索引中含有的ID有幾千萬,我們沒有辦法對幾千萬個數據在production DB上直接做匹配操作。

 

解決方案1 :我們在dev環境重現了這個問題,將代碼進行debug編譯後,使用production的索引,在匹配pattern處設置斷點,然後一邊看數據結構,一邊使用gdb將出問題的數據ID找出來。—> 這個方式弄了我一下午,其實效率不是很好。

 

 

解決方案2:[Much Better]

  1. 修改一下killing query,使用給定pattern的sub-pattern,小心避開導致crash的代碼。這樣搜索節點會返回匹配sub-pattern的一個ID List,由於使用sub-pattern,搜索節點返回的匹配數據的數量要比實際(使用完整pattern)多,但是卻比整個索引文件中的數據量小很多。
  2. 使用SQL SPOOL到數據庫中將ID屬於步驟1 ID List中的數據全部dump到一個臨時文件中。
  3. 使用grep, less 很容易就可以找到索引屬性符合給定pattern的ID了。

find.sql:

connect username/password@sid
set pagesize 1000
set linesize 1000
define filename= ‘result.txt’
prompt *** Spooling to &filename
spool &filename
select field1,field2,… from table where id in (
id1,id2,id3…idn);
spool off


 

-bash-3.00$ sqlplus /NOLOG
SQL> start find.sql
SQL> quit

 

-bash-3.00$ less result.txt

 

這裏補充一下尋找killing query的方法:只要core 文件沒有corruption,我們就可以拿到core發生時出錯線程的call stack,只有有函數參數或者棧變量保存了指向query的指針並且沒有被覆蓋,我們就可以使用mdb打印該內存,從而拿到killing query。

 

假設:

 

char* tp_Query = 0×80662457;

 

mdb> 0×80662457/S     –> 打印killing query。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章