我的系统是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
现在我有两个问题。
为什么在我的代码中
if ... else ...
不起作用?我的意思是mysql服务器没有问题,它可以执行"select id from test limit 1"
并得到结果,但脚本仍然运行代码以防else
万一。中
/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 变量中定义的路径可能不够。通常,请为所有命令提供完整路径。