
# Hive大SQL任务异常如何定位
#### 现象描述
MRS 3.5.0-LTS及之后版本，Hive执行的大SQL导致HiveServer或MetaStore内存快速增长，频繁Full GC使得业务无法正常运行，甚至导致实例异常重启。
#### 原因分析
- 查询大字段表导致HiveServer内存异常。
- 执行的SQL涉及的文件数过多，导致HiveServer内存异常。
- 执行的SQL涉及的分区数过多，导致HiveServer或MetaStore内存异常。
- MRS 3.6.0-LTS及之后版本，配置的堆内存不合理，导致HiveServer内存异常。
- MRS 3.6.0-LTS及之后版本，大量连接使用完未关闭，导致HiveServer内存异常。
 
#### 处理步骤
- 查询大字段表导致HiveServer内存异常场景 HiveServer查询结果分批次返回客户端，默认一批次返回1000条数据，大字段将大量占用实例内存，严重时将导致HiveServer OOM自动重启，当前实例正在运行的任务全部失败。
  大字段表查询异常时，客户端异常如[图1]所示，调用FetchResults时无法处理大字段，HiveServer异常重启，连接中断。
  图1大字段表查询异常   
  ![](https://support.huaweicloud.com/trouble-mrs/zh-cn_image_0000002380893794.png "点击放大")
  参考如下操作进行处理：
  1. 登录Manager页面，选择"运维 \> 事件"，在事件列表中查看Hive对象"进程重新启动"事件的详细信息，在"定位信息"中记录上报该事件的HiveServer主机名；并记录该事件的"产生时间"，即为HiveServer重启时间。
     单击"主机"，在主机列表中查看上报事件的主机名对应的节点的IP地址。
     
  
  2. 登录[1]查看到的重启的HiveServer节点，执行以下命令查看重启时是否生成JVM错误日志"hs_err_pid_\*log"：
     **ll /var/log/Bigdata/hive/hiveserver/hs_err_pid_\*log**
     - 是，执行[3]。
     
     - 否，执行[4]。
      
  
  3. 使用关键字"HiveSessionImpl.fetchResults"在"hs_err_pid_\*log"日志中查找正在获取返回结果的线程名称，执行[5]。
     图2查找线程名称   
     ![](https://support.huaweicloud.com/trouble-mrs/zh-cn_image_0000002381053662.png "点击放大") 
  
  4. 在HiveServer运行日志"/var/log/Bigdata/hive/hiveserver"目录下的HiveServer重启前一段时间内的运行日志文件中，查找OOM重启日志"Stopping HiveServer2 due to OOM"，并记录线程名称，执行[5]。
  
  5. 在HiveServer审计日志"/var/log/Bigdata/audit/hive/hiveserver/hive-audit.log"中使用编译线程名称查找HiveServer重启时间之前执行的查询SQL，并联系相关业务排查相关表是否包含大字段，停止对应的任务或修改相关表。
     图3查找SQL语句   
     ![](https://support.huaweicloud.com/trouble-mrs/zh-cn_image_0000002414453165.png "点击放大") 
   
- SQL涉及的文件数过多，导致HiveServer内存异常 HiveServer使用MapReduce引擎执行SQL时，提交任务前在HiveServer内存中读取文件进行切片，每个文件约占用2k内存，文件数过多将导致HiveServer内存异常。
  1. 登录Manager页面，选择"集群 \> 服务 \> Hive \> 配置 \> 全部配置"，查看是否配置如下参数： hive-ext.combine.input.file.limit.enable：用于设置是否开启读取文件数限制，默认值为"false"。开启该功能后，提交Hive任务前会统计读取的文件数并判断是否拦截该SQL，将增大对应任务执行的时间。
     hive-ext.combine.input.file.limit.threshold：若开启读取文件数限制参数，文件数超过该参数值的SQL将失败，默认值为1000000。
     - 是，执行[2]。
     
     - 否，执行[3]。
      
  
  2. 在HiveServer运行日志"/var/log/Bigdata/hive/hiveserver"目录下的HiveServer重启前一段时间内的运行日志文件中，使用关键字"The number of files exceeds"过滤超过限制值50%的线程名称，排查对应的SQL并联系业务人员进行处理。
  
  3. 联系业务人员确认是否需要开启相关参数限制大任务运行，文件数达到配置的限制值50%将打印提示日志"The number of files exceeds \*\*\*"，文件数达到限制值的SQL将失败。
     - 是，在HiveServer自定义配置中添加以上两个参数，并重启HiveServer实例。
     
     - 否，执行[4]。
      
  
  4. MRS 3.6.0-LTS之前版本，任务正常执行打印日志如[图4]所示，过滤异常时间段打印目录日志"Total number of paths"，但无扫描文件结束日志"Total input files to process"的线程，以及打印文件数"Total input files to process"超过10万的线程，并联系运维人员排查对应的SQL进行处理。
     图4任务运行日志   
     ![](https://support.huaweicloud.com/trouble-mrs/zh-cn_image_0000002414619721.png "点击放大")
     MRS 3.6.0-LTS及之后版本，任务正常执行会打印扫描的文件数，MapReduce引擎搜索关键字"Number of all splits"，Tez和Spark引擎搜索关键字"Total input files"，找到关键字日志内容中"files"的值超过10万对应的线程，并联系运维人员排查对应的SQL进行处理。
     
   
- SQL涉及的分区数过多，导致HiveServer或MetaStore内存异常 分区表查询或msck、analyze、alter删除大量分区等SQL执行不带分区过滤条件时，HiveServer将会查询所有分区名，再根据分区名分批查询分区对象，将占用大量HiveServer内存；带分区过滤条件时，HiveServer将条件下推到MetaStore，若满足条件的分区过多，MetaStore内存也会被大量占用。
  1. 确认异常的节点是HiveServer还是MetaStore。
     - HiveServer节点异常，执行[2]。
     
     - MetaStore节点异常，执行[3]。
      
  
  2. 在HiveServer运行日志"/var/log/Bigdata/hive/hiveserver"目录下的HiveServer异常的前一段时间内的运行日志文件中，使用关键字"The number of part size"过滤异常时间段扫描分区数大于10000的表，根据线程名排查相关SQL，联系运维人员进行处理。
  
  3. 登录Manager页面，选择"集群 \> 服务 \> Hive \> 配置 \> 全部配置"，查看是否配置以下参数：
     metastore.limit.partition.request：默认值为-1，配置该参数值大于0时，MetaStore会使用过滤条件提前count查询的分区数量，结果值超过此参数的分区过滤查询将失败。
     - 是，执行[4]。
     
     - 否，执行[5]。
      
  
  4. 在MetaStore运行日志"/var/log/Bigdata/hive/metastore"目录下的MetaStore异常的前一段时间内的运行日志文件中，使用关键字"The number of part size"过滤异常时间段扫描分区数大于10000的表，根据表名排查相关SQL，联系运维人员进行处理。
  
  5. 联系业务确认是否需要开启相关参数，限制大任务运行，配置后分区过滤将增加count操作，将增加查询耗时。
     - 是，在MetaStore自定义配置中添加相关参数并重启MetaStore实例。
     
     - 否，执行[6]。
      
  
  6. MRS 3.6.0-LTS之前版本，在MetaStore审计日志"/var/log/Bigdata/audit/hive/metastore"目录下的MetaStore异常的前一段时间内的日志文件中，使用关键字"get_partitions_by_expr"、"get_partitions"、"get_partitions_with_auth"和"get_partitions_by_filter"过滤异常时间段查询的表，排查相关SQL并联系运维人员进行处理。
     MRS 3.6.0-LTS及之后版本，在MetaStore运行日志"/var/log/Bigdata/hive/metastore"目录下的MetaStore异常的前一段时间内的日志文件中，使用关键字"The number of scanned partitions in"过滤异常时间段查询的表，排查相关SQL并联系运维人员进行处理。
     
   
- MRS 3.6.0-LTS及之后版本，配置的堆内存不合理，导致HiveServer内存异常场景 由于业务需要运行过多的SQL任务使得HiveServer或Metastore实例内存使用率很大，但系统内存仍使用的默认值，或者配置过小不能满足实际的需要，从而会导致进程频繁GC。方法如下：
  1. 在Manager首页，选择"运维 告警 告警"，"Hive服务进程堆内存使用超出阈值"告警展开详情页面，在定位信息中确认内存使用异常的节点是HiveServer还是MetaStore。
     - HiveServer节点异常，执行[2]。
     
     - MetaStore节点异常，执行[3]。
      
  
  2. 在Manager首页，选择"集群 \> 服务 \> Hive \> 实例"，单击告警上报的HiveServer，进入实例"概览"页面，单击图表区域右上角的下拉菜单，选择"定制 \> CPU和内存"，勾选"HiveServer内存使用率统计"，单击"确定"，查看HiveServer进程使用的堆内存是否长期达到或接近HiveServer进程设定的最大堆内存的阈值（默认95%）。
     - 是，执行[4]。
     
     - 否，操作结束。
      
  
  3. 在Manager首页，选择"集群 \> 服务 \> Hive \> 实例"，单击告警上报的MetaStore，进入实例"概览"页面，单击图表区域右上角的下拉菜单，选择"定制 \> CPU和内存"，勾选"MetaStore内存使用率统计"，单击"确定"，查看MetaStore进程使用的堆内存是否长期达到或接近MetaStore进程设定的最大堆内存的阈值（默认95%）。
     - 是，执行[4]。
     
     - 否，操作结束。
      
  
  4. 在Manager首页，选择"集群 \> 服务 \> Hive \> 配置"，选择"全部配置"，在左侧导航栏选择"HiveServer（角色）/MetaStore（角色） \> JVM"，将"HIVE_GC_OPTS/METASTORE_GC_OPTS"参数中"-Xmx"的值根据如下建议进行调整，单击"保存"保存配置，并重启Hive使配置生效。
     GC参数配置建议：
     - 将"-Xmx"值调整为默认值的2倍，例如"-Xmx"默认设置为2G时，调整"-Xmx"的值为4G。
     
     - 调整"-Xms"的值，使"-Xms"和"-Xmx"比值为1:2，这样可以避免JVM动态调整堆内存大小时影响性能。
     
     - 调小"-XX:CMSInitiatingOccupancyFraction"参数的值，加快GC频率，避免一次GC时间过长，例如修改值为60。
     
     - 将"-XX:NewSize"和"-XX:MaxNewSize"参数值大小设置为"-Xmx"参数值的四分之一。 如果现有集群的JVM配置里没有相关参数，但需要调整参数值，可在现有参数里加上需要调整的参数。
       
      
   
- MRS 3.6.0-LTS及之后版本，大量连接使用完未关闭导致HiveServer内存异常场景 创建Hive连接时，JDBC驱动对象、结果集对象ResultSet、语句对象Statement、内部缓冲区等都会存储在堆内存中，如果大量的连接未正常关闭，会持续占用堆内存空间，导致老年代对象堆积并触发回收需求，触发Full GC报错。
  1. 确认异常的节点是HiveServer还是MetaStore。
     - HiveServer节点异常，执行[2]。
     
     - MetaStore节点异常，执行[3]。
      
  
  2. 登录Manager页面，选择"集群 \> 服务 \> Hive \> 图表"，在"图表分类"中选择"Session"，在图表区域查看"HiveServer的session数统计"图表，确认HiveServer的session数是否出现持续增高的现象。
     - 是，执行[4]。
     
     - 否，操作结束。
      
  
  3. 登录Manager页面，选择"集群 \> 服务 \> Hive \> 实例 \> MetaStore \> 图表"，在"图表分类"中选择"连接数"，在图表区域查看"MetaStore连接数统计"图表，确认MetaStore的session数是否出现持续增高的现象。
     - 是，执行[5]。
     
     - 否，操作结束。
      
  
  4. 登录异常的HiveServer节点，执行以下命令：
     **grep 'OpenSession' /var/log/Bigdata/audit/hive/hiveserver/hive-audit.log \| awk '{print $9}' \| sort \| uniq -c \| sort**
     **grep 'CloseSession' /var/log/Bigdata/audit/hive/hiveserver/hive-audit.log \| awk '{print $9}' \| sort \| uniq -c \| sort**
     分析以上命令执行后的统计结果，根据审计日志中打开session和关闭session的日志记录信息排查session是否正常关闭，如果关闭session的日志信息少于打开session的日志，且相差的数量远大于正在运行的任务数量，则说明存在大量连接数未关闭的情况，需要业务侧检查是否有未正常关闭的连接、连接池配置的是否合理，如果存在需及时处理。
     
  
  5. 联系业务侧开发人员排查连接MetaStore的代码，检查是否有未正常关闭的连接、连接池配置的是否合理，如果存在需及时处理。
   
 
