专栏首页康中良的专栏crontab在一秒内刷新多次导致部分脚本不生效的问题分析
原创

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

今天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不生效的情况。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux中crontab-定时任务命令

    关于任务定时的命令crontab,在Linux中应用还算常见,这次为了配合开发完成一些辅助功能,以及一些备份更新等脚本,就需要crontab来完成,在windo...

    joshua317
  • Linux命令之Crontab——定时任务

    rontab命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动cron...

    浩Coding
  • 小知识点--crontab

    这两周学了很多东西,还把golang语言基本掌握了,收获还是挺多的。在做安全的过程中,有很多需要定时执行的任务,比如抓取主机数量,端口数据等,这都逃不开linu...

    七夜安全博客
  • 轻松使用crontab调度作业

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/...

    用户1148526
  • crontab中如何实现每隔多少天执行一次脚本

    1. # 下午6点到早上6点,每隔15分钟执行一次脚本 0,15,30,45 18-06 * * * /bin/bash $HOME/script.sh > ...

    拓荒者
  • Linux crontab命令

    crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供...

    刘亦枫
  • 循环执行定时任务crontab

    小编最近在将线上服务器实时的请求都转到测试机,但是由于请求量太多导致log不久就写满磁盘了,手动清理费事费力,因此考虑到自动清理,接触到corntab定时任务。...

    用户5521279
  • [Go 语言社区] redis数据清楚机制实现

    规则需求: 1 设计redis保存玩家用户的每天的数据,但是需要第二天清楚重置 程序设计: 1 程序触发事件保存数据。(满足数据保存需求) 2 清除脚本...

    李海彬
  • 【腾讯云的1001种玩法】关于Web服务器Nginx反向代理GitHub Page的一点思考(bash脚本)

    1 背景今天处理了下放在腾讯云的网站的服务器的一个小问题。由于我把简历放在了GithubPage上了,但是本人又不甘心只能墙外人看到,因此就通过墙内腾讯云服务器...

    ZNing
  • Linux命令之crontab

    Linux系统上面有很多计划性的工作,比如在某个时间点需要执行某个动作,在Linux中,一般使用crontab命令来实现控制计划任务,通过crontab 命令,...

    AsiaYe

扫码关注云+社区

领取腾讯云代金券