找出索引键值出错的数据ID

来源:互联网 发布:投屏软件 编辑:程序博客网 时间:2024/05/08 10:34

这个礼拜轮到我做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。