NO.33 要你命3000-宕机问题面面观 4.案例-获取全表数据致OOM

来源:互联网 发布:k8录音软件 编辑:程序博客网 时间:2024/05/03 08:10

 

    某年某月,这个月里发生了几次应用OOM,时间上一般发生在业务繁忙期(应用采用SUN JDK1.4.2.18 -Xmx2560m,一般观察繁忙期的JVM消耗最多也就到500m)。

    总算有一次实时观察JVM内存图时(NO.28宕机问题定位分析法 2.查看JVM监控图),重现了OOM现场:JVM消耗在不到一分钟里从400m冲到了上限。赶在JVM到顶前看了下URL访问表(NO.28宕机问题简单定位分析法 1.1查看长时驻留的请求URL),发现了一个驻留时间比较长的URL,抽丝剥茧,找到一段这样的代码:

 

    where 后面跟1=1,这样SqlUtils.convertString如果返回条件前面可以直接加上"and"

    SqlUtils.convertString有这么个规则:如果aColumnValuenull或空串,则其返回值为空串

    一查,aHugeTable 76多万笔数据......

    因此,初步判断(其实基本上是一定的了)aColumnValue为空……

    拉过来写这段代码的人,说页面上有JS校验,不可能传过来空值,我说校验的事你再去查,考虑到aColumn有索引,你先把那个语句改成这样,赶紧升级:

    紧接着,在更新环境之前,查看DBManager驻留的SQL(还好,系统还没有死干净,这个页面还能看的到),找到了“select ###### from aHugeTable where 1=1”,终100%验证了当初的推断。

    (之前,因为硬件问题,不能使用P6SPY(一种监控JDBCSQL的组件),因此自己改造了连接管理器类(DBManager),也实现了当SQL执行时间超过指定的阀值时,输出到一个文本中。这样做还是有个缺陷:没有执行完毕的是无法记录下来的,其实这些没执行完的很可能就是超级长时SQL。所以这个改造是必然的:每隔N秒,将DBmanager中当前执行的SQL刷新到一个文本中,这样一来,就没必要通过一个URL请求去看这些驻留SQL了:)

 

原创粉丝点击