作者:周鹏辉
1.文档编写目的
本文描述了一次CDH集群中,Hive锁表导致集群元数据MySQL的Hive MetaStore锁表,从而引起CM服务中断并且无法重启的异常分析。
- 文档概述
1.问题描述
2.问题分析
3.问题解决
4.总结
- 测试环境
1.CDH和CM版本:CDH5.15.1和CM5.15.1
2.集群启用Kerbeos OpenLDAP Sentry
2.问题描述
1.10月13日18:15分开始CM上监控到Hive出现如下异常:
同时查看“Hive MetaStore Cannary Server持续时间”在对应时间点达到11分钟,这是一个非常大的延迟值。
2.过了大概十多分钟,发现CM上进行操作反应很慢,尝试重启CM Server,发现无法重启。
3.这两个问题接着发生,当时为了尽快恢复业务,先尝试一个个Hive 实例进行重启,过了大概十分钟,再次尝试重启CM Server,发现可以正常启动了。
3.问题分析
3.1 Hive层面分析问题
1.首先查看HiveServer2和Hive MetaStore 的日志,发现10月13日6~7 PM期间的HiveServer2连接很频繁,HiveServer2和Hive MetaStore日志里发现有很多和数据库有关的报错【1】,这些错误会影响到canary test以及DDL操作。
【1】
Hive MetaStore日志:
代码语言:javascript复制2020-10-13 18:41:03,561 ERROR org.apache.hadoop.hive.metastore.RetryingHMSHandler: [pool-5-thread-121151]: Retrying HMSHandler after 2000 ms (attempt 7 of 10) with error: javax.jdo.JDOUserException: One or more instances could not be made persistent
at org.datanucleus.api.jdo.JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java:787)
...
Nested Throwables StackTrace:
java.sql.SQLException: The total number of locks exceeds the lock table size
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
HiveServer2 日志:
2.通过查找资料,MySQL报“The total number of locks exceeds the lock table size”应该是Hive的锁表或者大量查询导致innodb_buffer_pool_size不够大导致。
3.2 CM层面分析问题
1.查看cloudera-scm-server.log日志,发现从18:06开始一直到CM重启恢复正常,一直有The total number of locks exceeds the lock table size 【2】报错,此报错和我们在HiveServer2和Hive MetaStore 日志看到的是一样的。
【2】
CM Server 日志:
代码语言:javascript复制2020-10-13 18:06:43,097 ERROR 1587731234@scm-web-21766:org.hibernate.engine.jdbc.spi.SqlExceptionHelper: The total number of locks exceeds the lock table size
Caused by: java.sql.SQLException: The total number of locks exceeds the lock table size
2020-10-13 18:18:14,418 ERROR 2022524682@scm-web-21780:org.hibernate.engine.jdbc.spi.SqlExceptionHelper: The total number of locks exceeds the lock table size
2020-10-13 18:34:22,883 ERROR MainThread:org.hibernate.engine.jdbc.spi.SqlExceptionHelper: The total number of locks exceeds the lock table size
Caused by: java.sql.BatchUpdateException: The total number of locks exceeds the lock table size
通过查看Cloudera 官网,有一个相关的KB【3】说到这个问题
代码语言:javascript复制https://my.cloudera.com/knowledge/Services-Fail-when-Interacting-with-a-MySQL-Database-Error?id=70674
4.问题解决
1. 这个问题的本质应该是短时间内MySQL的某种资源的耗尽,我们可以尝试增加innodb_buffer_pool_size为256MB来解决此问题。
1).临时增大innodb_buffer_pool_size,重启mysql后会失效:
代码语言:javascript复制SET GLOBAL innodb_buffer_pool_size = 268435456;
show variables like '%innodb_buffer_pool%';
2).永久增大innodb_buffer_pool_size,在/etc/my.cnf的 [mysqld]下增加innodb_buffer_pool_size=256MB,重启MySQL。此方法会短暂影响集群使用,最好在变更停止集群的时候操作。
代码语言:javascript复制innodb_buffer_pool_size=256M
systemctl restart mysqld
show variables like '%innodb_buffer_pool%';
5.总结
1. 这个问题的本质应该是短时间内MySQL的某种资源的耗尽,可以尝试增加innodb_buffer_pool_size来增加这种资源。这个参数的具体值并有特别的说明【4】。这个需要根据集群上的实际运行情况自行调整,建议和DBA团队商量确定此值。
【4】
代码语言:javascript复制https://docs.cloudera.com/documentation/enterprise/latest/topics/cm_ig_mysql.html
2.当Hive处于高负载的时候,比较容易出现此问题。这次问题的根本原因就是因为某些大的hive query导致Hive压力增大和异常Hive query导致Hive lock table,而Hive MetaStore是在MySQL上的,从而也会导致大量的读写写入MySQL。而我们的CM 的元数据和Hive的元数据共用一个MySQL,因为Hive MetaStore的繁忙异常把MySQL的某种资源的耗尽,从而也引起CM异常,所以这两个问题是前后对应的关系。
3.我们最开始是通过一个个Hive实例重启,然后过了大概十分钟,再重启CM Server解决了此问题,本质是重启Hive实例的过程中中断了异常的hive query,从而把MySQL的资源释放出来。需要根本解决此问题还是要增加innodb_buffer_pool_size的值。