bash가 SSH 부분에서는 제대로 실행되지만 cronjob에서는 실행되지 않을 때 bash는 mysql을 다시 시작합니다.

bash가 SSH 부분에서는 제대로 실행되지만 cronjob에서는 실행되지 않을 때 bash는 mysql을 다시 시작합니다.

내 시스템은 centos 6.5입니다.

mysql이 충돌하는지 확인한 다음 서비스를 다시 시작하기 위해 간단한 bash 쉘을 작성했습니다. 나는 그것을 넣고 /home/myspace/mysql.sh chown root:root /home/myspace/mysql.shcrontab을 통해 매분마다 실행합니다.

#!/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(1분마다 오류를 쓰고 /home/myspace/restart_log.txtmysql 서버가 시작되지 않음).

이 문제의 원인은 무엇입니까 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

그러면 1분마다 데이터베이스를 ping하고 응답이 없으면 "다시 시작" 메시지를 발행합니다.

데이터베이스가 활성 상태인지 확인하기 위해 임의의 테이블을 쿼리하고 결과를 테스트할 필요가 없습니다.

이게 뭐야?공식 문서내가 말해야 할 것은평평한하위 명령:

평평한
서버가 사용 가능한지 확인하세요. mysqladmin의 반환 상태는 서버가 실행 중이면 0이고, 실행 중이 아니면 1입니다. Access Denied와 같은 오류가 발생하더라도 값은 0입니다. 이는 서버가 실행 중이지만 연결을 거부한다는 의미로 서버가 실행되지 않는 것과는 다릅니다.

더 나은 방법은 전용 프로세스 감시자를 사용하는 것입니다(예:감시 장치,갑자기 나타나다또는체계) 유지mysql그 과정이 살아있습니다.

답변2

로그에 표시된 것처럼(2번 지점) 이 else부분은 실행 중이지만 첫 번째 문에서만 종료됩니다.

실행되지 않는 것으로 의심되는 항목을 디버깅하려면 두 경로의 시작 부분에서 에코를 확인하세요. 문제가 없으면 언제든지 제거할 수 있습니다. 해당 부분의 빈 에코는 if도움이 되지 않습니다. 뭔가 인쇄됩니까? 인쇄 echo "takeing else route"되지 않은 것을 알 수 있지만 else.

작동하게 하려면 파일을 편집하고 (맨 페이지에서) 주석 처리 sudo해야 할 수도 있습니다 ./etc/sudoersrequiredtty

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분마다 다시 시작하시겠습니까? 다른 장애로 인해 서비스가 실패할 때 1분마다 다시 시작하려고 하는 것은 좋지 않습니다. (테스트 데이터베이스는 절대 삭제하지 마세요...) (마지막 실패 시간을 확인하는 더 스마트한 스크립트를 만들고 최소 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: 서비스를 다시 시작하는 것은 루트의 책임입니다. 루트를 실행하는 시스템 관리자는 서비스가 다시 시작될 때 매분마다 crontab을 확인하려고 합니다. 따라서 시스템 관리자에게 매직 스크립트를 루트로 실행하고 sudo를 사용하는 데 문제가 없을 것이라고 설득하십시오.

답변4

대부분의 경우 올바른 서비스를 지정해야 합니다. CENTOS 6.5에서는 다음과 같습니다.

service mysqld stop

아니요

service mysql stop

이것이 pkill이 작동하지 않는 이유이기도 합니다.pkill mysqld

하지만 실제 사용하는 명령은 service mysqld restart다음과 같습니다.피하다pkill을 완전히 사용하십시오.

cron 실행 시 기타 일반적인 고려 사항:

1) CentOS 6.5에서 에코 경로는 /bin/echo입니다.

2) cron을 루트로 실행하는 경우 sudo를 통해 명령을 실행하지 마십시오. (이렇게 하면 sudo로 인해 발생하는 tty/pty, 환경 및 권한 문제를 피할 수 있습니다.)

3) CentOS 6.5에서 pkill = /usr/bin/pkill의 전체 경로를 지정합니다.

4) CentOS 6.5에서 mysql = /usr/bin/mysql 경로를 지정합니다.

Emmanuel이 암시했듯이 PATH 변수에 정의된 경로는 cron을 통해 실행할 때 충분하지 않을 수 있습니다. 일반적으로 모든 명령에 대해 전체 경로를 제공합니다.

관련 정보