crontab导致CPU异常的问题分析及处理(r3笔记第100天)
今天查看数据库负载没有发现问题,但是当我使用top命令的时候,发现有一个进程占用了大量的cpu资源而且已经执行很长时间了。这一下子引起了我的注意。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25807 oraccbs1 25 0 8728 732 564 R 100.0 0.0 2021:19 /bin/sh -c /opt/app/oracle/xxxxxx/Script/DailyChk/chk_path_full.ksh PRODB 2>&1 >/opt/app/oracle/Script/DailyLog/chk_path_full.log
13578 oraccbs1 18 0 40.2g 49m 29m D 61.0 0.0 6:40.18 oraclePRODB (LOCAL=NO)
17085 oraccbs1 18 0 40.2g 48m 24m R 40.6 0.0 36:44.43 oraclePRODB (LOCAL=NO)
30894 oraccbs1 18 0 40.3g 56m 27m D 38.1 0.0 54:40.46 oraclePRODB (LOCAL=NO)
10616 oraccbs1 18 0 40.3g 54m 24m R 36.8 0.0 28:15.49 oraclePRODB (LOCAL=NO)
17089 oraccbs1 18 0 40.2g 49m 25m R 36.8 0.0 60:11.90 oraclePRODB (LOCAL=NO)
12103 oraccbs1 18 0 40.2g 31m 22m R 35.6 0.0 149:38.06 oraclePRODB (LOCAL=NO)
30898 oraccbs1 18 0 40.2g 50m 32m D 35.6 0.0 56:03.90 oraclePRODB (LOCAL=NO)
对于这个脚本我比较陌生,一般这些维护性的工作主要都是客户来做的。尝试查看了下这个脚本的内容,发现是一个检测脚本, 脚本的内容很清晰,是来监控归档目录和home目录的空间使用情况,当超过阀值的时候,就发送短信给响应的人来处理。 内容大体如下:
#Send Short Message if %used greater than 80% : ARCHIVE
PERC_ARCH_USED=`df -P ${ARCH_PATH}|awk '{ print $5 }'|grep "%"|tr -d "%"`
export casename=`uname -n`_${database}_Percent_Archive_Used_IS_${PERC_ARCH_USED}
if [[ $PERC_ARCH_USED -gt 80 ]]; then
sqlplus -s xxxxx @$myDir/Sql/sendsms.sql $casename
fi
#Send Short Message if %used greater than 80% : $ORACLE_HOME
PERC_HOME_USED=`df -P ${HOME_PATH}|awk '{ print $5 }'|grep "%"|tr -d "%"`
export casename=`uname -n`_${database}_Percent_HOME_Used_IS_${PERC_HOME_USED}
if [[ $PERC_HOME_USED -gt 80 ]]; then
sqlplus -s xxxxxx @$myDir/Sql/sendsms.sql $casename
fi
这样一个脚本的执行肯定执行一次就完了。它是从哪里执行的呢,首先想到的就是crontab。 crontab是在系统级作为作业自动执行的利器,可以进行各种细粒度的配置,使用也很方面。 先来查看一下crontab的情况,结果在crontab的最后发现一个配置就是正在执行的job.
>crontab -l
#------------------------------------------------
# Test Log DB for house keeping .....
#------------------------------------------------
#0,30 * * * * /opt/app/oracle/xxxxxx/Script/DailyChk/chk_path_full.ksh PRODB 2>&1 >/opt/app/oracle/Script/DailyLog/chk_path_full.log
这样来看似乎问题找到了原因,但是奇怪的是根据crontab里面的设置,这个job已经被禁用了,怎么还在运行? 毕竟这个问题还不能完全肯定是操作问题还是其他的原因导致的,就先不轻率的决定,把问题分给客户,从我的角度来说,怎么才能得到一些信息来说明这个问题才是关键。 首先是crontab的执行频率问题。如果没有接触过crontab可能会有些陌生。 crontab命令包含6个参数,命令的一些基本说明如下:
* * * * * command
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*或者 */1表示 第2列表示小时1~23(0表示0点) 第3列表示日期1~31 第4列表示月份1~12 第5列标识号星期0~6(0表示星期天) 第6列要运行的命令
在这个例子中。0,30是第一个参数,就代表每个小时的0分,30分执行一次下面的脚本。
0,30 * * * * /opt/app/oracle/xxxxxx/Script/DailyChk/chk_path_full.ksh PRODB 2>&1 >/opt/app/oracle/Script/DailyLog/chk_path_full.log
如果要求脚本在指定的时间段,比如只在5分,20分,30分的时候执行,
5,20,30 * * * * /opt/app/oracle/xxxxxx/Script/DailyChk/chk_path_full.ksh PRODB 2>&1 >/opt/app/oracle/Script/DailyLog/chk_path_full.log
如果要求脚本在指定的时间段,比如只在每天晚上的11:30执行,就可以写成下面的形式。
30 23 * * * /opt/app/oracle/xxxxxx/Script/DailyChk/chk_path_full.ksh PRODB 2>&1 >/opt/app/oracle/Script/DailyLog/chk_path_full.log
从配置来看,job是每隔半个小时执行一次,而且所做的检查工作也不复杂,执行时间应该会很短。配置中这个job已经被禁用,如果我们能够证明这个job是通过crontab执行的就能够说明是操作问题。因为crontab里面已经禁用,但是实际上job还在运行。 通过进程的信息,我们知道这个进程已经执行了近2021分钟,我们来推算一下执行的时间。2021/60=33个小时,从下午3点往前推33个小时,就是在29号早晨的7点左右开始执行的。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25807 oraccbs1 25 0 8728 732 564 R 100.0 0.0 2021:19 /bin/sh -c /opt/app/oracle/xxxxxx/Script/DailyChk/chk_path_full.ksh PRODB 2>&1 >/opt/app/oracle/Script/DailyLog/chk_path_full.log
这个时候日志就是最好的证明工具,可以在/var/spool/mail/oraccbs1下面找到相应的日志。 日志中最近的一次执行时间是在昨天的早晨7:30,之后就没有任何相关的日志了。
Mon Dec 29 07:30:01 2014
Return-Path: <oraccbs1@localhost.localdomain>
Received: from localhost.localdomain (xxxxx[127.0.0.1])
by localhost.localdomain (8.13.8/8.13.8) with ESMTP id sBT0U1mr013412
for <oraccbs1@localhost.localdomain>; Mon, 29 Dec 2014 07:30:01 +0700
Received: (from oraccbs1@localhost)
by localhost.localdomain (8.13.8/8.13.8/Submit) id sBT0U1Jh013347;
Mon, 29 Dec 2014 07:30:01 +0700
Date: Mon, 29 Dec 2014 07:30:01 +0700
Message-Id: <201412290030.sBT0U1Jh013347@localhost.localdomain>
From: root@localhost.localdomain (Cron Daemon)
To: oraccbs1@localhost.localdomain
Subject: Cron <oraccbs1@xxxxxx> /opt/app/oracle/xxxxxx/Script/DailyChk/chk_path_full.ksh PRODB 2>&1 >/opt/app/oracle/Script/DailyLog/chk_path_full.log
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
得到了这些基本信息,就能够基本确定问题了。 至于crontab的修改,可以使用crontab -e来完成。感觉就跟vi操作一样。客户做了确认之后,手工kill掉了那个job,那个问题就解决了。
- 配置远程访问Jupyter+腾讯云超划算活动上车
- HDU 4256 The Famous Clock
- ZOJ 1403&&HDU 1015 Safecracker【暴力】
- Torch7搭建卷积神经网络详细教程
- 爬虫入门到精通-HTTP协议的讲解
- 批量替换文件名和文本文件内容mac
- 抓取手机app的数据(摩拜单车)
- Hadoop离线数据分析平台实战——520项目总结Hadoop离线数据分析平台实战——520项目总结
- 爬虫入门到精通-mongodb的基本使用
- 拒绝撕逼,用数据来告诉你选择器到底哪家强
- 爬虫入门到精通-headers的详细讲解(If-modified-since)
- Linux配置网卡
- 【爬虫军火库】生成指定日期间的日期列表
- 手把手教你安装大数据开发测试环境手把手教你安装大数据开发测试环境
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- CentOS7+apache+php7+mysql5.7配置教程详解
- 如何利用SystemTap统计函数执行耗时详解
- 关于安装linux redhat后无法使用yum命令安装gcc-c++问题的解决过程
- 基于代码的自动化和无代码自动化
- Java Stream中map和flatMap方法
- 关于Apache shiro实现一个账户同一时刻只有一个人登录(shiro 单点登录)
- 视频上云安防视频云服务平台EasyCVR通过海康sdk协议接入多路设备拉流时出现部分设备拉流不稳定是什么原因?
- Centos6.x服务器配置jdk+tomcat+mysql环境(jsp+mysql)
- Linux的压缩和解压缩的方法总结
- RTSP/GB28181/HIKSDK/Ehome协议视频融合平台EasyCVR编译C++报参见“XXX”的声明错误
- 详解 Linux 常用目录的作用
- CentOS6环境下搭建路由器的方法
- centos7下NFS使用与配置的步骤
- 基于DOM4J的XML文件解析类
- Win7安装和配置Apache2.4服务器的详细方法