业务系统一个基础的表A,由于新增加了一个modifydate字段,用来标明插入日期或最新的更新日期,以便solr可以增量进行数据更新,提供检索查询服务。程序进行了调整,新的数据基本上都会保证modifydate不为空。但由于历史数据比较多,确定modifydate就比较困难了。
经过初步分析,大体上可以从几个角度进行modifydate初始化,主要是依据这个表中的其他日期字段作为参考,基本上可以保证绝大多数的历史数据都可以初始化,但仍有大约1000条左右实在没办法,也就没有再追究,反正是历史数据也就不再管了。
初始化完毕后,为了保证最新的数据都有modifydate,在oracle数据库层面,增加了一个特别的约束,之所以说特别,是因为这个非空约束,无法适用所有历史数据,但oracle提供了一个只对新数据产生作用的方法,这个感觉对于大家还是挺有用的,大家也不妨如有类似场景可以使用。
脚本大体如下:
alter table A add constraint A_check_notnull check(modifydateis not null) enable novalidate;
没错关键就是最后的两个关键字,只对新数据产生作用,旧的数据不用次约束来检查。如果不增加这两个关键字实际上相当于是enable validate,这是oracle默认设置,需要新旧数据都要满足,因此对于本文场景直接就会报错,无法创建这个约束。
好了,这个问题很好的解决了。大约过了10多天,业务部门来了一个紧急问题反馈,说是系统明显变慢,而且这个部门主要就是维护这个表。
这才想起好像前几天也有人反映这个问题,因为是年底,很多人做大的统计类查询,所以感觉系统稍微有点慢也正常,没有重视这件事。可是功能慢一定就和近期操作有关系吗?一时间实在想不出有什么关联,还是靠数据说话吧,这时候另外几个抓手工具就派上用场了。
大家不要以为是oracle本身的分析工具,确实不是,而是ELK的一个应用日志监控平台,这个是我们近两年在我的推动下自行建立起来的,而且用的也是很不错,除了抓取应用access日志,也抓取应用程序日志,既能了解应用日常运行情况,也能用来分析程序bug、客服问题。基本上我每天都在用,而且推动一个小组专门维护并建立了业务系统运行情况统计分析报表,有日报、月报,反正有这个工具在手,基本上不再抓瞎,也容易睡着觉了,哈哈!这可是基于数据事实的,大家都知道其实应用程序很难懂,而且在复杂运行环境下、并发、网络、客户端等都是可能影响的因素,但是数据不会说谎,以此为依据再深入分析就行,可以结合程序、用户操作、客户端,当然分析起来也不是很简单,需要经验,需要对各方面都要了解一些。
通过分析最近一个月的访问日志,特别是这个部门的IP网段、重点URL,确实发现了一些情况,自从去年12月22日开始,访问响应时间明显有变化,赶紧翻了一下数据初始化记录,果然就是21日晚上执行的。二者在时间上是吻合的。但是找到关联关系并无法解决问题,二者有因果关系吗?至少有很大可能。
把初始化脚本找出来,仔细再观察一下。
首先数据量没有明显变化,因为只是update其中两个字段,modifydate和remark,慢着,慢着,有一个备注字段,会是这个原因吗?
另外当时更新的数据量还有邮件作证,大约90多万条。绞尽脑汁苦苦思索,突然灵光一现,难道表内部结构产生变化了?毕竟更新了这么多数据量。
根据update脚本个人能想到的也就是存储结构了,存储结构会有什么变化呢?如果了解oracle的数据块存储的话,可能会想到,update两个字段,一个是从空到有日期,另外一个是备注增加内容,万一存储不下了怎么办?(此处不做深入讲解,个人能力有限,了解一点,大家如有兴趣可以研究一些oracle或一些大师的文章)
赶紧查oracle字典表,这个表大约有160多万,行迁移大约26万行,比例相当高。
select num_rows,chain_cnt from user_tab_statistics where table_name='A';
看来确实原因与此有关,时间、操作都基本吻合,考虑如何解决吧。
后续方案也是一波三折,让人唏嘘,下一篇续讲。