版权声明:本文由康中良原创文章,转载请注明出处: 
文章原文链接: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不生效的情况。

crontab在一秒内刷新多次导致部分脚本不生效的问题分析的更多相关文章

  1. 第三方apk内置因签名导致SystemUI未启动启动问题案例分析

    这个问题是刷完机正常开机后,发现手机无状态栏,下拉通知栏,按音量键也无法出现VolumeDialog,开始看到这个现象感觉是systemUI未编译到版本中去?或者是在systemserver中syst ...

  2. Jquery插件实现点击获取验证码后60秒内禁止重新获取

    通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能 先到官网(http://plugins.jquery.com/cookie/ )下载coo ...

  3. Linux crontab 实现每秒执行

    Linux crontab 实现每秒执行 linux crontab 命令,最小的执行时间是一分钟.如需要在小于一分钟内重复执行,可以有两个方法实现. 1.使用延时来实现每N秒执行 创建一个php做执 ...

  4. python量化分析系列之---5行代码实现1秒内获取一次所有股票的实时分笔数据

    python量化分析系列之---5行代码实现1秒内获取一次所有股票的实时分笔数据 最近工作太忙了,有一个星期没有更新文章了,本来这一期打算分享一些对龙虎榜数据的分析结果的,现在还没有把数据内的价值很好 ...

  5. 通向高可扩展性之路(推特篇) ---- 一个推特用来支撑1亿5千万活跃用户、30万QPS、22MB每秒Firehose、以及5秒内推送信息的架构

    原文链接:http://highscalability.com/blog/2013/7/8/the-architecture-twitter-uses-to-deal-with-150m-active ...

  6. OAF 使用 javascript 使某个按钮在5秒内不能重复点击

    首先要保证按钮是BUTTON,并且按钮事件设置firePartialAction. public class CuxXXXXPGCO extends OAControllerImpl { public ...

  7. 【转】安装Intel HAXM为Android 模拟器加速,30秒内启动完成

    http://www.cnblogs.com/Li-Cheng/p/4351966.html http://www.cnblogs.com/csulennon/p/4178404.html https ...

  8. 安装Intel HAXM为Android 模拟器加速,30秒内启动完成

    要求 必备知识 windows 7 基本操作. 运行环境 windows 7(64位); Android Studio 1.1.0;JDK 1.7.0_75(64位);android-sdk_r24 ...

  9. 微信公众号-5秒内不回复测试并处理方案,顺便复习php 时间执行

    在index.php中 file_put_contents('has_request.txt','请求时间:'.date('YmdHis')."\n",FILE_APPEND); ...

随机推荐

  1. 2016 Al-Baath University Training Camp Contest-1 F

    Description Zaid has two words, a of length between 4 and 1000 and b of length 4 exactly. The word a ...

  2. 2016年10月18日 星期二 --出埃及记 Exodus 19:2

    2016年10月18日 星期二 --出埃及记 Exodus 19:2 After they set out from Rephidim, they entered the Desert of Sina ...

  3. hibernate.properties

    hibernate.dialect=org.hibernate.dialect.MySQL5Dialect #hibernate.dialect=org.hibernate.dialect.Oracl ...

  4. 《redis-php中文参考手册》

    <redis中文手册>,将示例代码用php来实现,注意php-redis与redis_cli的区别(主要是返回值类型和参数用法). phpredis是redis的php的一个扩展,效率是相 ...

  5. PHP 之 FastCGI 与 mod_php 详解

    背景 PHP最常用的方式是以模块的方式(mod_php)运行在Apache中,也是Apache运行PHP的默认方式:但在Nginx中,Nginx又使用的是PHP-FPM,但是PHP-FPM到底是个什么 ...

  6. java配置问题

    先安装jdk.然后这样设置:**********************全为系统变量**************************变量名:JAVA_HOME变量值:D:\Program File ...

  7. 谢启鸿谈"如何学好高等代数"

    高等代数和数学分析.空间解析几何一起,并称为数学系本科生的三大基础课.所谓基础课,顾名思义,就是本科四年学习的所有数学课程,都是以上述三门课作为基础的.因此对一年级新生而言,学好这三门基础课,其重要性 ...

  8. iOS静态库和动态库的区别

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用 ...

  9. js对字符串的操作

    js对字符串的操作 concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串. indexOf() – 返回字符串中一个子串第一处出现的索引.如果没有匹配项,返回 -1 . charA ...

  10. git log 查看 提交历史

    在提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,可以使用 Git log 命令查看. 接下来的例子会用我专门用于演示的 simplegit 项目,运行下面的命令获取该项目源代码: git ...