最近在做项目中,有一个表格数据量很大,一天会增加40W+行记录,因为一般只使用最近一周的数据,为了减轻数据库压力,需要将之前数据备份到文件,然后从数据库中删除前一周之前的数据,于是采用脚本+crontab实现该需求。
一、执行脚本
#!/bin/bash # description: MySQL buckup shell script # author: evanxia # command: minute hour day-of-month month-of-year day-of-week comms # 30 2 * * 3 sh database_backup.sh > /dev/null 2>&1 EMAIL="xiascut@qq.com" USER="root" DATABASE="statistics" TABLE="statistics_data" # 备份文件存储路径 BACKUP_DIR="/data/database_backup" # 脚本执行日志 LOGFILE="${BACKUP_DIR}/backup.log" # 用日期格式作为文件名 DATE=`date +%Y%m%d_%H%M` NAME="${DATABASE}-${TABLE}-${DATE}" BACKUP_FILE="${NAME}.sql" TARGET_FILE="${BACKUP_DIR}/${NAME}.tgz" NOW=`date +%s` PREV_WEEK=$(($NOW-604800)) if [ ! -d ${BACKUP_DIR} ] then mkdir -p "${BACKUP_DIR}" fi #切换至备份目录 cd ${BACKUP_DIR} # 开始备份之前,将备份信息头写入日记文件 echo "" >> ${LOGFILE} echo "===================" >> ${LOGFILE} echo "BACKUP TABLE:${DATABASE}.${TABLE}" >> ${LOGFILE} echo "START TIME:" $(date +"%y-%m-%d %H:%M:%S") >> ${LOGFILE} # 备份 echo "-------------------" >> ${LOGFILE} mysqldump -u${USER} --no-create-info ${DATABASE} ${TABLE} --where="time<=${PREV_WEEK}"> ${BACKUP_FILE} # 判断数据库备份是否成功 if [ $? -eq 0 ] then tar czvf ${TARGET_FILE} ${BACKUP_FILE} >> ${LOGFILE} 2>&1 echo "[Success]-[${TARGET_FILE}] Database Backup!" >> ${LOGFILE} rm -f ${BACKUP_FILE} #删除原始备份文件,只需保留备份压缩包 echo "-------------------" >> ${LOGFILE} # 执行mysql命令,删除一周之前的所有数据 count=$(mysql -u${USER} -D ${DATABASE} -s -e "delete from ${TABLE} where time <= ${PREV_WEEK} ;select ROW_COUNT();") >> ${LOGFILE} 2>&1 if [ $? -eq 0 ] then echo "[Success]-Delete Data of Last Week, count=${count} !" >> ${LOGFILE} else echo "[Fail]-Delete Data of Last Week!" >> ${LOGFILE} #mail -s "[${TARGET_FILE}] Database Backup, Success.But Delete Data of Last Week on ${DATABASE}.${TABLE}, Fail, Time:${DATE} !" ${EMAIL} fi echo "END TIME:" $(date +"%y-%m-%d %H:%M:%S") >> ${LOGFILE} else echo "[Fail]-[${TARGET_FILE}] Database Backup!" >> ${LOGFILE} #mail -s "Database:${DATABASE}.${TABLE} Backup Fail, Time:${DATE} !" ${EMAIL} fi
脚本执行的逻辑大体如下图:
二、crontab周期任务
2.1、crontab介绍
Linux中,周期执行的任务一般由cron这个守护进程来处理 ps -ef | grep cron cron
读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间。
cron的配置文件称为“crontab”,是“cron table”的简写。
2.2、配置文件
1、/var/spool/cron/usernamexxx
这个目录下存放的是每个用户(包括root)的crontab任务,每个任务以创建者的名字命名,比如用户evan建的crontab任务对应的文件就是/var/spool/cron/evan
2、/etc/crontab
这个文件负责安排由系统管理员制定的维护系统以及其他任务的crontab。
3、/etc/cron.d/
这个目录用来存放任何要执行的crontab文件或脚本。
2.3、服务和命令
1、服务
/sbin/service crond start //启动服务 /sbin/service crond stop //关闭服务 /sbin/service crond restart //重启服务 /sbin/service crond reload //重新载入配置 /sbin/service crond status //查看服务状态
2、命令
crontab [-u user] [ -e | -l | -r ] crontab [-u user] file
-u user:用来设定某个用户的crontab服务;
file:file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。
-e:编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。
-l:显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。
-r:从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。
-i:在删除用户的crontab文件时给确认提示。
3、命令格式
minute hour day-of-month month-of-year day-of-week commands
* 代表所有的取值范围内的数字
/ 代表每的意思,"/5"表示每5个单位
– 代表从某个数字到某个数字
, 分开几个离散的数字
使用例子:
# 每天早上6点,注意单纯echo,从屏幕上看不到任何输出,因为cron把任何输出都email到root的信箱了。 0 6 * * * echo "Good morning." >> /tmp/test.txt # 每月1、10、22日的4 : 45重启smb 45 4 1,10,22 * * /etc/init.d/smb restart >/dev/null 2>&1 # 每月(1号凌晨4:42)去执行/etc/cron.monthly内的脚本 # "run-parts"这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名。 42 4 1 * * root run-parts /etc/cron.monthly
2.4、其他
1、开机自启动crond进程
chkconfig crond on
2、当手动执行脚本OK,但是crontab死活不执行时。这时必须大胆怀疑是环境变量惹的祸,并可以尝试在crontab中直接引入环境变量解决问题。
3、系统级任务调度与用户级任务调度
系统级任务调度主要完成系统的一些维护操作,用户级任务调度主要完成用户自定义的一些任务,可以将用户级任务调度放到系统级任务调度来完成(不建议这么做),但是反过来却不行,root用户的任务调度操作可以通过“crontab –uroot –e”来设置,也可以将调度任务直接写入/etc/crontab文件,需要注意的是,如果要定义一个定时重启系统的任务,就必须将任务放到/etc/crontab文件,即使在root用户下创建一个定时重启系统的任务也是无效的。
三、参考
1、http://blog.csdn.net/daniel_ustc/article/details/9395971
2、http://blog.csdn.net/ithomer/article/details/6817019
3、http://www.cnblogs.com/peida/archive/2013/01/08/2850483.html
+
转载标明出处:https://blog.evanxia.com/2016/07/861