场景:

数据交换平台,mysql全量数据导出到hive。

原理:查询mysql的最大,最小id. 然后根据并发,fetch大小,分配给不同线程的mysql连接执行,查询的数据通过hive的hcatelog api接口导入到hive表。

描述:

1:mysql表全量数据导入到hive.  发现进度到100%了,但是系统一直无法执行成功。

数据交换dump一个隐藏bug

2:使用jstack 查看进程,发现mysql一直在resultset无法close.

数据交换dump一个隐藏bug

3于是查看mysql的进程。mysql中有10几个进程一直是sleep(图中只截取了一个sleep的进程)。

数据交换dump一个隐藏bug
4:通过百度搜索如果有大量进程处于sleep,可以缩短waittimeout的时间。但是和dba对过配置之后,这是线上正常的配置。所以基本排除了wait_timeout超时的可能。

数据交换dump一个隐藏bug
5: 于是我手工Kill掉 mysql的process。假设kill掉precess, 任务已经可以自动close.然后成功。但是事实并不是这样。出现了如下的报错。

数据交换dump一个隐藏bug
6:于是之前的猜测都是错误的。通过jstark查看的线程情况,其实是片面的。我想到之前也曾经遇到过这种场景,可能的原因就是mysql主键最大值,最小值相差太大导致的。于是恍然大悟。max(id) - min(id) > count(*).... 系统还是在一直的按照fetchsize在批量拉取,但是拉取的数据都是0.所以进程会一直执行。

数据交换dump一个隐藏bug

 

解决:

这个问题在线上业务层应该会经常遇到,我们无法避免因为业务问题出现修数据的情况。

1:增大fetchsize的大小,从1w=>100w. 这个要考虑mysql的性能。而且对于线上重要的数据库不能使用这种操作,否则容易把数据库拉挂。

2:把一个任务替换成两个。过滤掉部分缺失的id.....

 

 

 

 

相关文章: