SR查询外表ES索引报错

前言

某天凌晨,因为云侧故障发生ES重启,导致客户端通过线上SR查询ES外表时一直报索引找不到错误,具体报错信息如下:

 ERROR 1064 (HY000): fetch es table [xxx] metadata failure: index[xxx] not found

当我们去通过原生es查询该索引时,发现索引是存在,因为正值大促期间,线上临时的解决方案是删掉表对表进行了重建,业务得到了恢复。

问题定位

代码定位该异常抛出位置为FE侧的EsRepository#runAfterCatalogReady


元数据同步准备.png

进入EsTable#syncTableMetaData方法,该方法看名字是同步表的元数据信息,内部实例化一个ES元数据状态的追踪器(EsMetaStateTracker), 通过EsMetaStateTracker#run方法启动


同步元数据.png

继续进入EsMetaStateTracker#run方法, 看起来是依次遍历并执行各个查询阶段
同步具体执行阶段.png

builtinSearchPhase接口: 有以下三种实现,分别用来获取ES的Mapping,Version, Partition;


SearchPhase实现类.png

继续进入MappingPhase#execute方法, 该方法通过getMapping获取json映射信息
execute函数.png

继续进入EsRestClient#getMapping方法,该方法是构造请求Path, 然后调用execute方法具体执行,此处如果获取不到indexMapping, 会抛出异常, 此处注意有个includeTypeName决定了url的构建方式。
getMapping.png

继续进入EsRestClient#execute方法,该方法就是具体执行http请求,返回Mapping信息。
具体http请求.png

通过使用athas工具跟踪,我们发现当线上ES为6.3.2版本时,includeTypeName值为true,这不符合业务代码中的逻辑,因为源代码中的逻辑只有大于7.X版本值该值才为true, 后续经过在测试环境安装指定版本的es进行重启并结合代码内部逻辑,定位到了变量值异常的原因:

ES某天凌晨宕机重启,在重启的过程中,client.version()获取版本的时候因为连不上es, 所以抛出了异常,异常被捕获之后,版本号被赋值为7.X, includeTypeName设置为true。当ES重启之后,版本号重新更新为了6.3.2,但是此时includeTypeName并没有重新被修改false。这个地方有一个corner case是:只有低版本变到高版本处理(见下图),当高版本降为低版本时,并没有去重新修改includeTypeName=false的操作。

同步es版本号.png

MappingPhase的预处理方法.png

最后

由于某些原因,通过athas定位线上问题的过程这里没有给出,主要涉及公司的一些敏感信息。在对线上问题进行修复之后,同社区进行了沟通并提交了我们修复的PR。目前该PR已经被合并,这个bug在SR2.4以下版本均存在,具体请参考:https://github.com/StarRocks/starrocks/pull/13995

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容