当 bash 在 SSH 部分运行良好但在 cronjob 中运行不佳时,bash 重新启动 mysql

当 bash 在 SSH 部分运行良好但在 cronjob 中运行不佳时,bash 重新启动 mysql

我的系统是centos 6.5,

我写了一个简单的bash shell来检查mysql是否崩溃,然后重新启动服务。我把它放进去,/home/myspace/mysql.sh chown root:root /home/myspace/mysql.sh然后通过 crontab 每分钟运行一次。

#!/bin/bash
mysql --host="localhost" --user="root" --password="password" --database="test" --execute="select id from test limit 1"
if [ $? -eq 0 ]; then echo "";
else
 /usr/bin/sudo service mysql stop
 pkill mysql
 /usr/bin/sudo service mysql start
 echo "error $(date)" >> /home/myspace/restart_log.txt
fi

现在我有两个问题。

  1. 为什么在我的代码中if ... else ...不起作用?我的意思是mysql服务器没有问题,它可以执行"select id from test limit 1"并得到结果,但脚本仍然运行代码以防else万一。

  2. /var/log/sucure,显示root : sorry, you must have a tty to run sudo ; TTY=unknown ; PWD=/root ; USER=root ; COMMAND=/sbin/service mysql stop. root : sorry, you must have a tty to run sudo ; TTY=unknown ; PWD=/root ; USER=root ; COMMAND=/sbin/service mysql start。并且mysql服务器宕机了。

更新: 现在我尝试了@Anthon给出的代码:

#!/bin/bash
RESULT=`mysql --host="localhost" --user="root" --password="password" --database="test" --execute="select browser from test limit 1"`
if [ $? -eq 0 ]; then 
   echo "mysql select ok"
else
  /usr/bin/echo "mysql select failed"
  sudo service mysql stop
  pkill mysql
  /usr/bin/sudo service mysql start
  echo "error $(date)" >> /home/myspace/restart_log.txt
fi

SSH部分运行良好(返回 mysql select ok)

但不工作cronjob(每分钟写入错误/home/myspace/restart_log.txt并且mysql服务器从未启动)

这个问题是由 引起的吗PATH?或者privileges?怎么解决呢?谢谢。

解决 谢谢大家,终于我解决了。 @Sigi 的方法也许不错,但不适用于我的情况。 @Anthon 的答案写得比我好,但仍然不起作用。 @Emmanuel,鉴于答案比其他人更接近。经过长时间的测试,我将最终的工作代码分享给大家。

#!/bin/bash
PATH=/bin:/usr/bin:/sbin:/usr/local/bin
# cronjob need clear where is the path
# mysql under path /usr/local/bin
mysql --host="localhost" --user="root" --password="password" --database="test" --execute="select id from test limit 1"
if [ $? -eq 0 ]; then echo "";
# mysql run well nothing to do, make a
else
 sudo /etc/init.d/mysql stop
 pkill /usr/local/bin/mysql
# It should be pkill /usr/local/bin/mysql, not pkill mysql, wrong write will cause below code not working
 sudo /etc/init.d/mysql start
 sudo /etc/init.d/httpd restart
# Some strange behave, after mysql restart, apache will die, so should add httpd restart 
 echo "error $(date)" >> /home/myspace/restart_log.txt
fi

答案1

您想要做的是检查数据库服务器进程是否仍然存在。 MySQL为此提供了一个命令:mysqladmin ping

我建议您将以下内容放入系统 crontab 中(编辑文件/etc/crontab):

* * * * *  root  /usr/bin/mysqladmin --host="localhost" --user="root" --password="password" ping || /usr/sbin/service mysql restart

这将每分钟 ping 数据库一次,如果没有响应则发出“重新启动”消息。

无需查询任意表并测试结果来确定数据库是否处于活动状态。

这是什么官方文档不得不说的是子命令:


检查服务器是否可用。如果服务器正在运行,则 mysqladmin 的返回状态为 0,如果未运行,则返回状态为 1。即使出现诸如拒绝访问之类的错误,该值也为 0,因为这意味着服务器正在运行但拒绝连接,这与服务器未运行不同。

更好的是使用专用的进程观察程序(例如监控,暴发户或者系统)以保持mysql进程活着。

答案2

正如您的日志所示(第 2 点),该else部分正在执行,但仅在第一条语句中退出。

如果您想调试您怀疑未执行的某些内容,请确保在两个路径的开头进行回显(当事情正常时您可以随时删除它们)。您在该部分中的空回if显没有帮助,它会打印一些东西吗?您会注意到它没有被打印,但更好的是echo "takeing else route"else.

要开始sudo工作,您可能必须编辑/etc/sudoers文件并注释掉requiredtty(从手册页):

requiretty      If set, sudo will only run when the user is logged in
                to a real tty.  When this flag is set, sudo can only be
                run from a login session and not via other means such
                as cron(8) or cgi-bin scripts.  This flag is off by
                default.

要获得反馈,您的脚本应如下所示:

#!/bin/bash
mysql --host="localhost" --user="root" --password="password" --database="test" --execute="select id from test limit 1"
if [ $? -eq 0 ]; then 
   echo "mysql select ok"
else
   echo "mysql select failed"
 /usr/bin/sudo service mysql stop
 pkill mysql
 /usr/bin/sudo service mysql start
 echo "error $(date)" >> /home/myspace/restart_log.txt
fi

答案3

题外话:你真的想每分钟重新启动服务吗?当服务由于其他故障而失败时,尝试每分钟重新启动是很糟糕的。 (永远不要删除测试数据库...)(您可以制作一个更智能的脚本来检查上次失败时间并在重试和向操作员发送邮件之前等待至少 1 小时)
主题:当您不能依赖mysql的返回值,你可以尝试选择一些字符串:

FLAG="$(mysql --host="localhost" --user="root" --password="password" --database="test" \
   --execute="select count(*) as MYSPECIALFLAG from test")"
if [[ ${FLAG} != *MYSPECIALFLAG* ]]; then
   my_restart_function
fi

其他问题:没有终端的sudo:重新启动服务是root的责任。运行 root 的系统管理员希望在每分钟重新启动服务时检查自己的 crontab。因此,请说服您的系统管理员,他希望以 root 身份运行您的魔法脚本,并且使用 sudo 不会出现问题。

答案4

最有可能的是 - 您需要指定正确的服务,在 CENTOS 6.5 上它将是

service mysqld stop

不是

service mysql stop

这也是 pkill 不起作用的原因,您需要pkill mysqld

但真正要使用的命令service mysqld restart避免完全使用 pkill 。

运行 cron 时的其他一般注意事项:

1)在CentOS 6.5上,echo的路径是/bin/echo

2) 如果您以 root 身份运行 cron,请不要通过 sudo 运行命令(这将避免 sudo 引入的 tty/pty、环境和权限问题)

3)在CentOS 6.5上指定pkill = /usr/bin/pkill的完整路径

4)在CentOS 6.5上指定mysql的路径= /usr/bin/mysql

正如 Emmanuel 所暗示的,通过 cron 运行时,PATH 变量中定义的路径可能不够。通常,请为所有命令提供完整路径。

相关内容