zoukankan      html  css  js  c++  java
  • crontab在一秒内刷新多次导致部分脚本不生效的问题分析

    版权声明:本文由康中良原创文章,转载请注明出处: 
    文章原文链接:https://www.qcloud.com/community/article/182

    来源:腾云阁 https://www.qcloud.com/community

    今天ob在几台DB上发现crontab中的监控任务,从来没有执行。但操作一下crontab的配置crontab –e + wq,监控任务就能正常执行,重启cron也能正常执行。

    出问题的机器crontab的情况如下:

    问题挺奇怪,第一条crontab执行正常,第二条crontab一直没有执行。

    第一条正常,证明cron有正常运行。DB监控任务的crontab是凯丽系统自动安装的,理论上不会存在突然出错的情况。

    问题定位:

    cron出bug了? 第二个任务确实没有执行,还是执行前遇到问题退出,刚好日志又打印到/dev/null了..

    考虑到crontab执行历史在系统日志里会有记录,检查var/log/message日志如下,整*/5的分钟点只有crontab的第一个任务。

    crontab第二个任务确实没执行,应该是crontab出了点问题,再看看在修改crontab的那一刻发生了什么?

    根据crontab最后一次修改的时间(2012-06-18 17:51:01),检查系统日志如下:

    刚巧,在同一秒内修改了2次crontab。根据凯丽安装监控的顺序,第一个crontab应该是在安装第一条crontab任务,第二个crontab应该是在安装第二个crontab任务。

    猜想:根据cron的工作原理,难道在增加第一个任务之后,cron加载了crontab的配置(/var/spool/cron/tabs/mysql),但是在增加第二个任务之后,cron没有加载该配置? 如果是这样,那么cron判断是否需要加载配置文件的机制是如何的呢?

    网上文档稀少,直接看代码。

    在网上找到一个debian的cron源代码: cron_3.0pl1.orig.tar.gz

    解压打开,查看cron的执行过程:
    在cron.c 的main函数中,cron的主函数代码如下:

    cron_sleep(): crontab 最小执行单位是分钟,因此是每60秒执行一次.TargetTime += 60;

    load_database(): 检查crontab的配置文件是否有更新,如果有更新,则重新load,否则使用上次记录的database cron_tick( ): 实际执行任务查看cron是如何加载crontab的配置文件的,进入load_database()函数.
    database.c :

    可以看到,在cron加载配置的时候,会先获取/var/spool/cron/tabs 目录stat信息,然后获取用户的crontab配置文件的stat信息,然后比较上一次统计的修改时间与tabs目录、crontab配置文件的最后修改时间,如果一致则不重新load,否则重新load crontab配置文件。

    stat为系统函数调用,该函数取得的结构体的st_mtime的单位为秒。

    至此,我们可以得出这样的结论:

    由于两次crontab修改时间均在同一秒,而cron的加载是以crontab配置文件的最后修改时间(秒级)来判断文件是否需要更新。当出现以下场景,第二次对crontab的修改就会失效(不仅是增加)。

    crontab失效的场景:

    而这个场景,刚好是我们的DB出现crontab失效的情况。

    crontab的刷新机制,是以crontab文件的最后修改时间为准.

    因此,如果在一秒内对crontab进行多次(大于1次)操作,就可能出现后修改的crontab不执行!

    当再次对crontab文件进行保存操作时,cron会重新加载配置文件,crontab生效.

    解决办法:

    该问题是由于在一秒内执行多次crontab变更导致。因此解决办法有3个:

    1. 在凯丽每次操作crontab的时候增加sleep 1的操作

    2. 在凯丽每次crontab操作完成之后,sleep 1,强制刷新crontab的最后更新时间

    3. 合并并行的crontab操作为一次操作,减少对crontab的操作频率

    根据凯丽的情况,选择第二个方案对现有代码改动最小。

    提醒:

    脚本尽量不要在同一秒内多次操作crontab内容,否则可能导致crontab不生效的情况。

  • 相关阅读:
    SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)
    麦咖啡导致电脑不能上网
    SharePoint 2013 Central Admin 不能打开
    SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
    SharePoint 2013 APP 开发示例 系列
    synthesize(合成) keyword in IOS
    Git Cmd
    简单的正则匹配
    Dropbox
    SQL Server Replication
  • 原文地址:https://www.cnblogs.com/purpleraintear/p/6051454.html
Copyright © 2011-2022 走看看