因此,我正在对数据库进行自动备份。备份脚本在手动运行以及 Cron 运行预定的每小时和每日备份时均能正常工作。但是,每周和每月备份都会失败。
我(显然)不确定,但我认为我的问题出在 cron 配置上。也许是因为脚本在午夜多次运行而导致冲突?我不确定这是否可能,但如果可能的话,我希望得到有关微调 crontab 的说明。
我的计划任务:
# * * * * * user-name command to be executed
00 * * * * /data/backup.sh -h #hourly
00 00 * * * /data/backup.sh -d #daily
00 00 * * 6 /data/backup.sh -w #weekly
00 00 1 * * /data/backup.sh -m #monthly
编辑:我更新了我的 crontab 以交错分钟,但它仍然不起作用:
# * * * * * user-name command to be executed
00 * * * * /data/backup.sh -h #hourly
05 00 * * * /data/backup.sh -d #daily
10 00 * * 6 /data/backup.sh -w #weekly
15 00 1 * * /data/backup.sh -m #monthly
我通过以下命令访问它们:
sudo crontab -u my_user_group_name -e
Linux版本:
$ cat /proc/version
Linux version 3.10.0-514.6.1.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) ) #1 SMP Wed Jan 18 13:06:36 UTC 2017
备份脚本本身运行良好,当作为手动 shell 脚本运行时,使用任何标志(-h、-d、-w、-m)。它一定会成功。它是一个 Wordpress 备份脚本,使用wp-cli
,本质上序列化 MariaDB 数据库。为了完整起见,我已将脚本包含在这个问题的末尾。
我仔细研究了一般来自此答案的 cron 故障排除建议,但我没有看到任何适用于我的问题的内容:
- 我不认为问题出在备份脚本本身,因为问题只在 cron 运行期间发生,而不是在 shell 中直接运行时发生。很高兴有人能证明我错了。
- 我认为问题不在于更广泛的环境,而在于 cron 配置本身(上文),因为问题仅在某些 cron 运行期间发生,但其他 cron 运行成功。例如,Crontab 的名称正确,权限正确,等等。
- cron 答案没有提及 cron 运行的频率,运行之间的冲突,或者我认为可能是问题背后的其他动态。
以下是所讨论的备份目录的权限(在 中)/data/backup/
。如您所见,每小时和每周目录具有相同的权限。
drwxr-xr-x. 2 libsys libsys 4096 Feb 20 00:05 daily
drwxrwxr-x. 2 root backup 4096 Feb 20 10:00 hourly
-rw-rw-r--. 1 root backup 35644 Feb 20 10:00 log.txt
drwxrwxr-x. 2 root backup 4096 Feb 13 11:23 manual
drwxrwxr-x. 2 aberry3 aberry3 4096 Feb 6 10:36 monthly
drwxrwxr-x. 2 aberry3 aberry3 4096 Feb 6 10:36 weekly
我刚刚注意到每日权限没有组写入;我会修复这个问题并在一周后再回来查看。不过,这可能是一个转移注意力的借口;我的问题不在于每日备份,它工作正常:只有每周和每月备份没有发生。
以下是备份脚本:
#!/bin/bash
# Usage
# This script will make a backup of the WordPress database, into the
# defined backup directory, "/data/backups".
# Options are -hdwm, for "hourly", "daily", "weekly", "monthly"; these
# simply put the backups into different subdirectories. Running the script
# without options creates four backups, one in each directory.
# The script also "cleans up" the directories afterward.
# constants
WP_DIR=/var/www/wordpress/docroot
DATA_DIR=/data/backups
LOG=$DATA_DIR/log.txt
# vars
TIMESTAMP=$(date +%Y-%m-%d.%H-%M-%S)
# run all commands from WP root directory
cd $WP_DIR
# the meat of the backup script
backup () { # arguments: "hourly", "daily", "weekly", "monthly", "manual"
INTERVAL=$1
BACKUP_DIR=$DATA_DIR/$INTERVAL
# create directory hierarchy if not exists
mkdir -p $BACKUP_DIR
# create backup
FILENAME=$(printf "%s/wp-mariadb-%s.sql" "$BACKUP_DIR" "$TIMESTAMP")
/usr/local/bin/wp db export $FILENAME
# make sure backup happened
if [ -s $FILENAME ]
then
echo "√ backup OK $TIMESTAMP $INTERVAL" >> $LOG
else
echo "!!! backup FAIL $TIMESTAMP $INTERVAL" >> $LOG
exit 1 # terminate and indicate error
fi
# clean up backup directory
BACKUP_FILES=$BACKUP_DIR/*.sql
case $INTERVAL in
"hourly")
KEEP=24
;;
"daily")
KEEP=7
;;
"weekly")
KEEP=4
;;
"monthly")
KEEP=12
;;
"manual")
KEEP=999 # don't automatically delete manual backups
;;
esac
# evaluate which files to delete from directory
for BACKUP in $BACKUP_FILES; do
# if (BACKUP_FILES quantity > KEEP)
# and if (BACKUP age in minutes) > (minutes ago)
# delete backup
ARR=($BACKUP_FILES) # convert to array
LEN=${#ARR[@]} # length of array
# if we have too many backups...
if (($LEN > $KEEP)); then
# ...delete the backup.
rm $BACKUP
fi
done
}
# run particular backup scripts depending on options
while getopts "hdwma" arg; do
case $arg in
h)
backup "hourly"
;;
d)
backup "daily"
;;
w)
backup "weekly"
;;
m)
backup "monthly"
;;
a)
# a stands for all; backup everywhere
backup "hourly"
backup "daily"
backup "monthly"
;;
*)
echo "Error: command not recognized"
echo "!!! backup FAIL $TIMESTAMP illegal option in '$1'" >> $LOG
;;
esac
done
这是我的日志文件的一个示例,仅显示了问题:
...
√ backup OK 2017-02-17.22-00-01 hourly
√ backup OK 2017-02-17.23-00-01 hourly
√ backup OK 2017-02-18.00-00-02 hourly
√ backup OK 2017-02-18.00-05-01 daily
!!! backup FAIL 2017-02-18.00-10-02 weekly
√ backup OK 2017-02-18.01-00-01 hourly
√ backup OK 2017-02-18.02-00-02 hourly
√ backup OK 2017-02-18.03-00-02 hourly
√ backup OK 2017-02-18.04-00-02 hourly
√ backup OK 2017-02-18.05-00-01 hourly
√ backup OK 2017-02-18.06-00-01 hourly
√ backup OK 2017-02-18.07-00-01 hourly
√ backup OK 2017-02-18.08-00-02 hourly
√ backup OK 2017-02-18.09-00-02 hourly
√ backup OK 2017-02-18.10-00-01 hourly
√ backup OK 2017-02-18.11-00-04 hourly
√ backup OK 2017-02-18.12-00-03 hourly
√ backup OK 2017-02-18.13-00-02 hourly
√ backup OK 2017-02-18.14-00-02 hourly
√ backup OK 2017-02-18.15-00-01 hourly
√ backup OK 2017-02-18.16-00-02 hourly
√ backup OK 2017-02-18.17-00-04 hourly
√ backup OK 2017-02-18.18-00-02 hourly
√ backup OK 2017-02-18.19-00-02 hourly
√ backup OK 2017-02-18.20-00-02 hourly
√ backup OK 2017-02-18.21-00-02 hourly
√ backup OK 2017-02-18.22-00-03 hourly
√ backup OK 2017-02-18.23-00-02 hourly
√ backup OK 2017-02-19.00-00-03 hourly
√ backup OK 2017-02-19.00-05-02 daily
√ backup OK 2017-02-19.01-00-03 hourly
√ backup OK 2017-02-19.02-00-02 hourly
√ backup OK 2017-02-19.03-00-01 hourly
...
答案1
此命令:
sudo crontab -u my_user_group_name -e
结合备份目录的用户和组所有权的多样性:
drwxr-xr-x. 2 libsys libsys 4096 Feb 20 00:05 daily
drwxrwxr-x. 2 root backup 4096 Feb 20 10:00 hourly
-rw-rw-r--. 1 root backup 35644 Feb 20 10:00 log.txt
drwxrwxr-x. 2 root backup 4096 Feb 13 11:23 manual
drwxrwxr-x. 2 aberry3 aberry3 4096 Feb 6 10:36 monthly
drwxrwxr-x. 2 aberry3 aberry3 4096 Feb 6 10:36 weekly
看起来有点可疑。我猜实际用户(假设您没有真正名为的用户my_user_group_name
)不是aberry3
。如果我大胆猜测,我会说libsys
正在运行脚本的用户是组成员backup
但不是组成员aberry3
。
由于您无论如何都要在脚本中创建目录,请尝试重命名现有目录并让脚本使用运行脚本的实际用户的所有者/组来创建它们。
答案2
尝试,
sudo chown root:每周备份
答案3
向脚本添加更多日志记录。
在脚本的第一行添加“-x”。
#!/bin/bash -x
这将为您提供发送到“MAILTO”cron 选项中指定的地址的电子邮件中更详细的脚本输出。
此外,根据文档(https://wp-cli.org/commands/db/export/)你可以在“wp db export”命令中添加“--debug”。试试这个。
/usr/local/bin/wp db export --debug $FILENAME
您可以发布脚本失败时收到的邮件内容,这应该为您/我们提供足够的数据来查明问题。