web-dev-qa-db-ja.com

「servicemysqldstop」がタイムアウトします(「mysqldは停止していますが、サブシステムがロックされている」ことがわかりました)

64ビットのCentOS5サーバーにyum経由でmysqlとサーバーをインストールしました。正常に起動しますが、停止しようとすると停止し、「Ctrl-C」を押す必要があります。次に、「service mysqld status」を実行すると、次のように表示されます。

mysqld dead but subsys locked

Ps auxを実行しましたが、mysqlが見つかりません。 「servicemysqldstart」を介してmysqldを再起動すると正常に機能します。それを止めようとすると、同じ問題が発生します。

その後、/var/lock/subsys/mysqldがまだ存在していることに気づきました。 mysqldを実行しているときに、/var/run/mysqld/mysqld.pidをチェックし、実行中のサービスのpidと一致しました。

Mysqlを再インストールし、すべてのファイルと構成を削除しようとしましたが、役に立ちませんでした。

何をすべきか?

編集:

/etc/init.d/mysqldファイル、特にstop関数にいくつかのechoステートメントを追加しました。

stop(){
        if [ ! -f "$mypidfile" ]; then
            # not running; per LSB standards this is "ok"
            action $"Stopping $prog: " /bin/true
            return 0
        fi  
        echo "beginning stop sequence"
        MYSQLPID=`cat "$mypidfile"`
        if [ -n "$MYSQLPID" ]; then
            /bin/kill "$MYSQLPID" >/dev/null 2>&1
            echo "killing pid $MYSQLPID"
            ret=$?
            if [ $ret -eq 0 ]; then
                echo "return code $ret after kill attempt"
                TIMEOUT="$STOPTIMEOUT"
                echo "timeout is set to $STOPTIMEOUT"
                while [ $TIMEOUT -gt 0 ]; do
                    /bin/kill -0 "$MYSQLPID" >/dev/null 2>&1 || break
                    sleep 1
                    let TIMEOUT=${TIMEOUT}-1
                    echo "timeout is now $TIMEOUT"
                done
                if [ $TIMEOUT -eq 0 ]; then
                    echo "Timeout error occurred trying to stop MySQL Daemon."
                    ret=1
                    action $"Stopping $prog: " /bin/false
                else
                    echo "attempting to del lockfile: $lockfile"
                    rm -f $lockfile
                    rm -f "$socketfile"
                    action $"Stopping $prog: " /bin/true
                fi
            else
                action $"Stopping $prog: " /bin/false
            fi
        else
            # failed to read pidfile, probably insufficient permissions
            action $"Stopping $prog: " /bin/false
            ret=4
        fi
        return $ret
}

これは、サービスを停止しようとしたときに得られる結果です。

[root@server]# service mysqld stop
beginning stop sequence
killing pid 9145
return code 0 after kill attempt
timeout is set to 60
timeout is now 59
timeout is now 58
timeout is now 57
timeout is now 56
timeout is now 55
timeout is now 54
timeout is now 53
timeout is now 52
timeout is now 51
timeout is now 50
timeout is now 49

コードを見ると、whileループから抜け出すことはなく、ロックファイルを削除できないように思われます。私はこれを間違って解釈していますか?他のサーバーで同じファイルをチェックしましたが、同じコードを使用しています。私は唖然とします。

[〜#〜] edit [〜#〜]:whileループ部分

 /bin/kill -0 "$MYSQLPID" >/dev/null 2>&1 || break

何らかの理由で、戻りコードを認識していません。 service mysqld stopが呼び出されたとき、プロセスはすでに強制終了されていますが、ループの発生を許可していない理由がわかりません。

[〜#〜] edit [〜#〜]:さらにテストすると、/bin/killの呼び出しとkillの呼び出しの間に奇妙な動作が見られますが、どうやら異なるコードが返されるのはなぜですか? ?????:

[root@server]# /bin/kill 25200
kill 25200: No such process
[user@server]# echo ${?}
0
[root@server]# kill 25200
-bash: kill: (25200) - No such process
[root@server]# echo ${?}
1

[〜#〜] edit [〜#〜]:root以外のユーザーとしてログオンし、「kill」と「/ bin/kill」を実行しようとすると、驚くべき結果が得られました。

[notroot@server ~]$ kill -0 23232
-bash: kill: (23232) - No such process
[notroot@server ~]$ echo $?
1
[notroot@server ~]$ /bin/kill -0 23232
kill 23232: No such process
(No info could be read for "-p": geteuid()=501 but you should be root.)
[notroot@server ~]$ echo $?
0

Root以外のユーザーとしてkillおよびbin/killを実行すると、「情報を読み取ることができませんでした」というエラーが他のサーバーに表示されません。

[〜#〜] edit [〜#〜]:quantaによって記述されたログを追加し、mysqlログもチェックアウトしました:

開始と停止の後、mysqlログはこれを示します:

110918 00:11:28 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
110918  0:11:28 [Note] Plugin 'FEDERATED' is disabled.
110918  0:11:28  InnoDB: Initializing buffer pool, size = 16.0M
110918  0:11:28  InnoDB: Completed initialization of buffer pool
110918  0:11:29  InnoDB: Started; log sequence number 0 44233
110918  0:11:29 [Warning] 'user' entry 'root@server' ignored in --skip-name-resolve mode.
110918  0:11:29 [Warning] 'user' entry '@server' ignored in --skip-name-resolve mode.
110918  0:11:29 [Note] Event Scheduler: Loaded 0 events
110918  0:11:29 [Note] /usr/libexec/mysqld: ready for connections.
Version: '5.1.58-ius'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  Distributed by The IUS Community Project
110918  0:11:34 [Note] /usr/libexec/mysqld: Normal shutdown

110918  0:11:34 [Note] Event Scheduler: Purging the queue. 0 events
110918  0:11:34  InnoDB: Starting shutdown...
110918  0:11:39  InnoDB: Shutdown completed; log sequence number 0 44233
110918  0:11:39 [Note] /usr/libexec/mysqld: Shutdown complete

110918 00:11:39 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended

次に、tmp /mysql.logで:

kill 23080: No such process
kill 23080: No such process
kill 23080: No such process
kill 23080: No such process
kill 23080: No such process
kill 23080: No such process
kill 23080: No such process
kill 23080: No such process
kill 23080: No such process
kill 23080: No such process

停止プロセスを途中で停止したので、タイムアウトを待つ必要はありません。プロセスが強制終了されたようです。問題は、まだ"kill"および"/bin/kill"とは異なるリターンコードにあると思います。

5
lamp_scaler

まず最初に:非常によくできていて、体系的で徹底的なデバッグ、良い仕事。

RHEL 5.6ボックスでは、存在しないpidを強制終了しようとすると、常に1の戻りコードが返されます。ルートユーザーと非特権ユーザーの両方として、フルパスとコマンド名だけで試してみました。また、簡潔なkill XXX: No such processのみが表示され、複雑なエラーメッセージは表示されません。

rpm -Vv util-linuxを実行して、誰かが/bin/killを新しく改良されたバージョンに置き換えていないかどうかを確認することをお勧めします。 rpm検証でファイルが元の状態であると表示された場合でも、/bin/killの名前を変更して、動作中のマシンからバイナリをコピーしてみます。ファイルの置き換えが役に立ち、変更の正当な原因が明らかにならない場合は、rpm検証の出力に関係なく、マシンが危険にさらされていると思います。

2
Paweł Brodacki