分享

hive1.1.0查询遇到问题分析及解决办法

阿飞 2015-6-29 18:31:29 发表于 问题解答 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 28234
本帖最后由 阿飞 于 2015-6-29 18:47 编辑
问题导读
1.对于sql语句遇到的问题,本文是如何调试的?
2.hive.optimize.remove.identity.project=false的作用是什么?
3.hive如何远程debug?






背景
在查询以下语句的时候结果不正确,无法join tab1.tm=tab2.hour。如果存在以下类似的语句,有子查询的group by,外层有join语句,返回的结果不正确,无法join成功。
[mw_shl_code=sql,true]SELECT tab1.ip, tab1.tm, tab2.HOUR
FROM (
    SELECT c.ip,c.lkid, c.HOUR,MIN(s.HOUR) AS tm FROM Tclick_iphone c JOIN Tsndata_iphone s
    ON c.ip=s.ip GROUP BY c.ip,c.lkid,c.HOUR
) tab1 JOIN Tsndata_iphone tab2
ON tab1.ip=tab2.ip AND tab1.tm=tab2.HOUR;[/mw_shl_code]


分析
首先是构造可重复测试语句,减少所需要查询的数据,然后尝试替换其中的语句,检查语句是否正常。缩小错误范围。
测试中发现如果把子查询替换为表,能够正常查询。另外在随机测试的过程中,发现这样的语句也可以成功。
[mw_shl_code=sql,true]SELECT tab1.ip, tab1.tm, tab2.HOUR
FROM (
    SELECT c.ip,c.lkid, MIN(s.HOUR) AS tm FROM Tclick_iphone c JOIN Tsndata_iphone s
    ON c.ip=s.ip GROUP BY c.ip,c.lkid,c.HOUR
) tab1 JOIN Tsndata_iphone tab2
ON tab1.ip=tab2.ip AND tab1.tm=tab2.HOUR;[/mw_shl_code]



单步调试1
反复单步调试对比错误、正确语句,发现第二步的输入和正确的语句不一样。
这是字节数组,还有个解析这个字节数组的描述信息(多少个字段,各个字段的类型) ,正确语句输入的内容为:
[3, 14, 49, 50, 49, 46, 50, 51, 54, 46, 49, 54, 52, 46, 50, 56, -114, 11, -82, 0, 0, 0, 0, 0, 0, 0, 0, 0]
描述信息有两个字段

错误的语句输入内容为:
[15, 14, 49, 50, 49, 46, 50, 51, 54, 46, 49, 54, 52, 46, 50, 56, 4, 119, 105, 102, 105, -114, 10, -84, -114, 11, -82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
描述信息有两个字段
这个字节第一位是判断符号,判断是否是null,后面的字符如果是string,第一位是字符长度。如果是数字,会有类似这样的bytes [-114, 10, -84]
从这里看出输入的内容不一致,但字段描述信息却一样。那错误可能发生在输入的内容不正确或者字段描述解析不正确。

单步调试2 – 输入内容、字段描述从哪里来
从explain知道第二步的输入来源于子查询的输出,也就是子查询的reduce输出。单步调试发现字段描述是在编译语句阶段已经确定好,每个Operator已经确定了输出的字段数和类型。
另外在对比explain中,发现正确的语句比错误的语句多了个SELECT Operator(列裁剪)。

单步调试3 – 为什么错误语句少了SELECT Operator?
范围缩小到语句的语法编译。
发现代码中会打印一些日志出来,可以修改hive的log4j文件改为debug模式,发现语句优化的过程中把SELECT Operator去掉了。
优化前

[mw_shl_code=bash,true]TS[0]-FIL[2]-RS[3]-JOIN[6]-SEL[7]-GBY[8]-RS[9]-GBY[10]-SEL[11]-FIL[13]-RS[14]-JOIN[17]-SEL[18]-FS[19]
ppd.PredicatePushDown: After PPD
TS[0]-FIL[21]-RS[3]-JOIN[6]-SEL[7]-GBY[8]-RS[9]-GBY[10]-FIL[20]-SEL[11]-RS[14]-JOIN[17]-SEL[18]-FS[19][/mw_shl_code]
优化后
[mw_shl_code=bash,true]TS[0]-FIL[21]-RS[3]-JOIN[6]-GBY[8]-RS[9]-GBY[10]-FIL[20]-RS[14]-JOIN[17]-SEL[18]-FS[19][/mw_shl_code]


可以看到在GBY[10]-FIL[20]-SEL[11]-RS[14]中,SEL[11]被去掉了。
单步调试语句的优化过程,由于优化步骤有21个,使用二分法检查到底是运行到哪一个优化器把SEL去掉了。
最终发现是 IdentityProjectRemover 优化器。
这个优化器的功能是根据前后输入输出,去掉不必要的SELECT Operator。检查到这里,没有继续往下查了,还有一些为什么FIL[20] row schema为什么是两个字段,但实际输出内容却不是的问题。

搜索
使用关键词IdentityProjectRemover搜索源代码,看看这个代码最新版本有没有修改过。搜索发现一些issue,找到了关闭这个优化器的参数。hive.optimize.remove.identity.project=false,另外发现在hive1.2.0版本,增加了另一个参数,间接默认关闭了这个优化。
另外发现这个issue和我们这次的错误类似,应该是同一个问题 HIVE-10996 。这个issue里面有说明更详细的错误原因,见评论
这个issue已经有补丁,但目前还没有合并到主干。它的解决的方法是在GBY-FIL-SEL中插入一个SEL,变成GBY-SEL-FIL-SEL


当前解决方案
设置参数 hive.optimize.remove.identity.project=false 关闭这个优化器
这个优化是从1.1.0版本引入(我们当前使用的版本)


技巧
刚开始debug的时候很慢,而且越用越慢,后来发现限制hive客户端使用内存有一定效果。可能debug时需要dump内存。
使用 hive –debug 可以远程debug
使用 hive –hiveconf hive.root.logger=DEBUG,console 可以临时打印日志



没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条