Bei vielen Benutzern ist dieser Fehler beim Starten von MySQL aufgetreten. Lassen Sie mich zunächst klarstellen, dass dieser Fehler darauf zurückzuführen ist, dass MySQL über das Serviceskript gestartet wird. Beim Starten der MySQL-Instanz über mysqld_safe oder mysqld wird dieser Fehler nicht gemeldet. Was ist also der konkrete Grund für diesen Fehler? Haha, wenn Sie sich nicht für den Analyseprozess interessieren, können Sie direkt zur Zusammenfassung am Ende des Artikels springen ~ Zusammenfassen Als nächstes analysieren wir das Startskript des MySQL-Dienstes Das vollständige Skript lautet wie folgt: #!/bin/sh # Copyright aufgegeben 1996 TCX DataKonsult AB & Monty Program KB & Detron HB # Diese Datei ist gemeinfrei und wird mit KEINER GARANTIE jeglicher Art geliefert # Start-/Stopp-Skript für den MySQL-Daemon. # Normalerweise wird dies in /etc/init.d abgelegt (zumindest auf Maschinen, die auf SYSV R4 basieren # Systeme) und verknüpft mit /etc/rc3.d/S99mysql und /etc/rc0.d/K01mysql. # Wenn dies erledigt ist, wird der MySQL-Server gestartet, wenn die Maschine # gestartet und heruntergefahren, wenn das System ausfällt. # Kommentare zur Unterstützung von chkconfig unter RedHat Linux # chkconfig: 2345 64 36 # Beschreibung: Eine sehr schnelle und zuverlässige SQL-Datenbank-Engine. # Kommentare zur Unterstützung von LSB-Init-Skriptkonventionen ### BEGINNEN INIT INFO # Bietet: mysql # Erforderlicher Start: $local_fs $network $remote_fs # Sollte starten: ypbind nscd ldap ntpd xntpd # Erforderlicher Stopp: $local_fs $network $remote_fs # Standard-Start: 2 3 4 5 # Standard-Stopp: 0 1 6 # Kurzbeschreibung: MySQL starten und stoppen # Beschreibung: MySQL ist eine sehr schnelle und zuverlässige SQL-Datenbank-Engine. ### ENDE INIT INFO # Wenn Sie MySQL an einem anderen Ort als /usr/local/mysql installieren, dann # müssen Sie eine der folgenden Aktionen ausführen, damit dieses Skript funktioniert: # # - Führen Sie dieses Skript aus dem MySQL-Installationsverzeichnis aus # - Erstellen Sie eine /etc/my.cnf-Datei mit den folgenden Informationen: # [mysqld] # basedir=<Pfad zum MySQL-Installationsverzeichnis> # - Fügen Sie das Obige zu einer beliebigen anderen Konfigurationsdatei hinzu (zum Beispiel ~/.my.ini) # und kopiere my_print_defaults nach /usr/bin # - Fügen Sie den Pfad zum MySQL-Installationsverzeichnis zur Variable basedir hinzu # unten. # # Wenn Sie andere MySQL-Variablen beeinflussen möchten, sollten Sie Ihre Änderungen vornehmen # in /etc/my.cnf, ~/.my.cnf oder anderen MySQL-Konfigurationsdateien. # Wenn Sie das Basisverzeichnis ändern, müssen Sie auch das Datenverzeichnis ändern. Diese können # durch Einstellungen in den MySQL-Konfigurationsdateien überschrieben. basedir= Datenverzeichnis= # Standardwert in Sekunden, nach dem das Skript eine Zeitüberschreitung beim Warten # für den Serverstart. # Der Wert hier wird durch den Wert in my.cnf überschrieben. # 0 bedeutet, überhaupt nicht zu warten # Negative Zahlen bedeuten, unendlich zu warten service_startup_timeout=900 # Verzeichnis für RedHat/SuSE sperren. lockdir='/var/lock/subsys' lock_file_path="$lockdir/mysql" # Die folgenden Variablen werden nur festgelegt, damit mysql.server Dinge finden kann. # Legen Sie einige Standardeinstellungen fest mysqld_pid_file_path= wenn test -z "$basedir" Dann basedir=/usr/local/mysql bindir=/usr/local/mysql/bin wenn test -z "$datadir" Dann datadir=/usr/local/mysql/data fi sbindir=/usr/local/mysql/bin libexecdir=/usr/local/mysql/bin anders bindir="$basedir/bin" wenn test -z "$datadir" Dann Datenverzeichnis="$basedir/data" fi sbindir="$basedir/sbin" libexecdir="$basedir/libexec" fi # datadir_set wird verwendet, um zu bestimmen, ob datadir gesetzt wurde (und sollte es auch sein # *nicht* innerhalb des --basedir=-Handlers festgelegt.) datadir_set= # # Verwenden Sie nach Möglichkeit LSB-Init-Skriptfunktionen zum Drucken von Nachrichten # lsb_functions="/lib/lsb/init-functions" wenn test -f $lsb_functions; dann . $lsb_funktionen anders log_success_msg() { echo " ERFOLGREICH! $@" } log_failure_msg() { echo " FEHLER! $@" } fi PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin" Exportpfad mode=$1 # starten oder stoppen [ $# -ge 1 ] && verschieben other_args="$*" # ungewöhnlich, aber erforderlich, wenn es von einer RPM-Upgrade-Aktion aufgerufen wird # Erwartet: „--skip-networking --skip-grant-tables“ # Sie werden hier absichtlich nicht überprüft, da es in der Verantwortung liegt # des Autors der „spec“-Datei, um nur korrekte Argumente anzugeben. Fall `echo "testing\c"`, `echo -n testing` in *c*,-n*) echo_n= echo_c= ;; *c*,*) echo_n=-n echo_c= ;; *) echo_n= echo_c='\c' ;; esac parse_server_arguments() { für arg tun Fall "$arg" in --basedir=*) basedir=`echo "$arg" | sed -e ‚s/^[^=]*=//‘` bindir="$basedir/bin" wenn test -z "$datadir_set"; dann Datenverzeichnis="$basedir/data" fi sbindir="$basedir/sbin" libexecdir="$basedir/libexec" ;; --datadir=*) datadir=`echo "$arg" | sed -e ‚s/^[^=]*=//‘` datadir_set=1 ;; --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e ‚s/^[^=]*=//‘` ;; --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e ‚s/^[^=]*=//'` ;; esac Erledigt } warte_auf_pid () { verb="$1" # erstellt | entfernt pid="$2" # Prozess-ID des Programms, das die PID-Datei bearbeitet pid_file_path="$3" # Pfad zur PID-Datei. ich = 0 avoid_race_condition="durch erneute Prüfung" während Test $i -ne $service_startup_timeout; mache Fall "$verb" in 'erstellt') # Warten Sie, bis eine PID-Datei erstellt wird. test -s "$pid_file_path" && i='' && break ;; 'ENTFERNT') # warten, bis diese PID-Datei verschwindet Prüfung! -s "$pid_file_path" && i='' && break ;; *) echo "wait_for_pid () Verwendung: wait_for_pid erstellt|entfernt pid pid_file_path" Ausfahrt 1 ;; esac # wenn der Server nicht läuft, wird die PID-Datei nie aktualisiert wenn test -n "$pid"; dann wenn kill -0 "$pid" 2>/dev/null; dann : # der Server läuft noch anders # Der Server wurde möglicherweise zwischen der letzten PID-Dateiprüfung und jetzt beendet. wenn test -n "$avoid_race_condition"; dann race_condition vermeiden="" weiter # Nochmals prüfen. fi # es gibt nichts, was die Datei beeinflussen würde. log_failure_msg "Der Server wurde beendet, ohne die PID-Datei ($pid_file_path) zu aktualisieren." return 1 # nicht mehr warten. fi fi echo $echo_n ".$echo_c" i=`Ausdruck $i + 1` Schlaf 1 Erledigt wenn test -z "$i" ; dann log_erfolg_msg Rückgabe 0 anders log_failure_msg Rückgabe 1 fi } # Argumente aus der Datei my.cnf abrufen, # die einzige Gruppe, die von nun an gelesen wird, ist [mysqld] wenn test -x ./bin/my_print_defaults Dann print_defaults="./bin/my_print_defaults" elif test -x $bindir/my_print_defaults Dann print_defaults="$bindir/meine_druck_defaults" elif test -x $bindir/mysql_print_defaults Dann print_defaults="$bindir/mysql_print_defaults" anders # Versuchen Sie, das Basisverzeichnis in /etc/my.cnf zu finden conf=/etc/meine.cnf drucken_standardwerte= wenn test -r $conf Dann subpat='^[^=]*basedir[^=]*=\(.*\)$' dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf` für d in $dirs Tun d=`echo $d | sed -e 's/[ ]//g'` wenn test -x "$d/bin/my_print_defaults" Dann print_defaults="$d/bin/meine_druck_defaults" brechen fi wenn test -x "$d/bin/mysql_print_defaults" Dann print_defaults="$d/bin/mysql_print_defaults" brechen fi Erledigt fi # Hoffe, es ist im PATH ... aber ich bezweifle es test -z "$print_defaults" && print_defaults="meine_print_defaults" fi # # Standarddatei aus 'basedir' lesen. Wenn dort keine Standarddatei vorhanden ist, # prüfen, ob es sich am alten (veralteten) Ort (datadir) befindet und von dort lesen # extra_args="" wenn test -r "$basedir/my.cnf" Dann extra_args="-e $basedir/my.cnf" anders wenn test -r "$datadir/my.cnf" Dann extra_args="-e $datadir/my.cnf" fi fi parse_server_arguments `$print_defaults $extra_args mysqld-Server mysql_server mysql.server` # # PID-Datei festlegen, falls nicht angegeben # wenn test -z "$mysqld_pid_file_path" Dann mysqld_pid_file_path=$datadir/`hostname`.pid anders Fall "$mysqld_pid_file_path" in /* ) ;; * )mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;; esac fi Fall "$mode" in 'Start') # Daemon starten # Absicherung (relative Pfade, Core Dumps...) cd $basedir echo $echo_n "MySQL wird gestartet" wenn test -x $bindir/mysqld_safe Dann # Geben Sie mysqld zusätzliche Argumente mit der Datei my.cnf. Dieses Skript # kann beim nächsten Upgrade überschrieben werden. $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & wait_for_pid hat "$!" erstellt "$mysqld_pid_file_path"; Rückgabewert=$? # Sperre für RedHat / SuSE erstellen wenn test -w "$lockdir" Dann berühren Sie "$lock_file_path" fi beenden $return_value anders log_failure_msg "MySQL-Server konnte nicht gefunden werden ($bindir/mysqld_safe)" fi ;; 'stoppen') # Daemon stoppen. Wir verwenden hier ein Signal, um nicht wissen zu müssen, # Root-Passwort. wenn test -s "$mysqld_pid_file_path" Dann mysqld_pid=`cat "$mysqld_pid_Dateipfad"` wenn (kill -0 $mysqld_pid 2>/dev/null) Dann echo $echo_n "MySQL wird heruntergefahren" Beenden Sie $mysqld_pid # mysqld sollte die PID-Datei beim Beenden entfernen, warten Sie also darauf. wait_for_pid hat "$mysqld_pid" "$mysqld_pid_file_path" entfernt; Rückgabewert=$? anders log_failure_msg "MySQL-Serverprozess #$mysqld_pid läuft nicht!" rm "$mysqld_pid_dateipfad" fi # Sperre für RedHat / SuSE löschen wenn test -f "$lock_file_path" Dann rm -f "$lock_file_pfad" fi beenden $return_value anders log_failure_msg "MySQL-Server-PID-Datei konnte nicht gefunden werden!" fi ;; 'Neustart') # Stoppen Sie den Dienst und unabhängig davon, ob er # läuft oder nicht, starten Sie es erneut. wenn $0, stopp $other_args; dann $0 Start $andere_args anders log_failure_msg "Der laufende Server konnte nicht gestoppt werden. Daher wird ein Startversuch abgelehnt." Ausfahrt 1 fi ;; 'neu laden'|'erzwungenes Neuladen') wenn test -s "$mysqld_pid_file_path" ; dann mysqld_pid lesen < "$mysqld_pid_file_path" kill -HUP $mysqld_pid && log_success_msg "MySQL-Dienst wird neu geladen" berühren Sie "$mysqld_pid_file_path" anders log_failure_msg "MySQL PID-Datei konnte nicht gefunden werden!" Ausfahrt 1 fi ;; 'Status') # Überprüfen Sie zunächst, ob die PID-Datei vorhanden ist wenn test -s "$mysqld_pid_file_path" ; dann mysqld_pid lesen < "$mysqld_pid_file_path" wenn kill -0 $mysqld_pid 2>/dev/null; dann log_success_msg "MySQL läuft ($mysqld_pid)" Ausfahrt 0 anders log_failure_msg "MySQL läuft nicht, aber die PID-Datei existiert" Ausfahrt 1 fi anders # Versuchen Sie, den passenden mysqld-Prozess zu finden mysqld_pid=`pidof $libexecdir/mysqld` # testen, ob mehrere PIDs vorhanden sind pid_count=`echo $mysqld_pid | wc -w` wenn test $pid_count -gt 1; dann log_failure_msg "Mehrere MySQL laufen, aber die PID-Datei konnte nicht gefunden werden ($mysqld_pid)" Ausfahrt 5 elif test -z $mysqld_pid ; dann wenn test -f "$lock_file_path" ; dann log_failure_msg "MySQL läuft nicht, aber die Sperrdatei ($lock_file_path) existiert" Ausfahrt 2 fi log_failure_msg "MySQL läuft nicht" Ausfahrt 3 anders log_failure_msg „MySQL läuft, aber die PID-Datei konnte nicht gefunden werden“ Ausfahrt 4 fi fi ;; *) # Verwendung Basisname=`Basisname "$0"` echo "Verwendung: $basename {start|stop|restart|reload|force-reload|status} [MySQL-Serveroptionen]" Ausfahrt 1 ;; esac Ausfahrt 0 Definieren Sie zunächst die relevanten Parameter basedir= Datenverzeichnis= # Standardwert in Sekunden, nach dem das Skript eine Zeitüberschreitung beim Warten # für den Serverstart. # Der Wert hier wird durch den Wert in my.cnf überschrieben. # 0 bedeutet, überhaupt nicht zu warten # Negative Zahlen bedeuten, unendlich zu warten service_startup_timeout=900 # Verzeichnis für RedHat/SuSE sperren. lockdir='/var/lock/subsys' lock_file_path="$lockdir/mysql" In, basedir bezieht sich auf das Verzeichnis, in dem das komprimierte Binärpaket entpackt wird, zum Beispiel /usr/local/mysql. datadir bezieht sich auf das Datenverzeichnis service_startup_timeout=900 definiert das Zeitlimit für den Start des MySQL-Dienstes. Wenn der Dienst nicht innerhalb von 900 Sekunden gestartet werden kann, wird das Skript beendet. lockdir='/var/lock/subsys' In Bezug auf /var/lock/subsys lautet die Erklärung im Internet wie folgt und wird später verwendet. Im Allgemeinen prüft der System-Shutdown-Prozess (durch Ausgabe eines Shutdown-Signals und Aufrufen des eigenen Prozesses des Dienstes) die Dateien unter /var/lock/subsys und fährt jeden Dienst einzeln herunter. Wenn ein laufender Dienst keine entsprechende Option unter /var/lock/subsys hat. Wenn das System heruntergefahren wird, wird dieser Dienst wie ein normaler Prozess beendet. Wenn Sie sich die Skripte unter /etc/rc.d/init.d ansehen, können Sie feststellen, dass jeder Dienst beim Ausführen den entsprechenden Dienst unter /var/lock/subsys überprüft. Viele Programme müssen feststellen, ob bereits eine Instanz ausgeführt wird. Dieses Verzeichnis ist für das Programm ein Zeichen, um festzustellen, ob eine Instanz ausgeführt wird. Wenn diese Datei beispielsweise vorhanden ist, bedeutet dies, dass xinetd bereits ausgeführt wird, andernfalls nicht. Natürlich muss das Programm entsprechende Beurteilungsmaßnahmen enthalten, um wirklich feststellen zu können, ob eine Instanz ausgeführt wird. Normalerweise wird dieses Verzeichnis von einem /var/run-Verzeichnis begleitet, in dem die PID der entsprechenden Instanz gespeichert wird. Wenn Sie Skripte schreiben, werden Sie feststellen, dass diese beiden Verzeichnisse zusammen leicht feststellen können, ob viele Dienste ausgeführt werden, zugehörige Informationen zum Ausführen usw. Bestimmen Sie basedir und datadir # Legen Sie einige Standardeinstellungen fest mysqld_pid_file_path= wenn test -z "$basedir" Dann basedir=/usr/local/mysql bindir=/usr/local/mysql/bin wenn test -z "$datadir" Dann datadir=/usr/local/mysql/data fi sbindir=/usr/local/mysql/bin libexecdir=/usr/local/mysql/bin anders bindir="$basedir/bin" wenn test -z "$datadir" Dann Datenverzeichnis="$basedir/data" fi sbindir="$basedir/sbin" libexecdir="$basedir/libexec" fi In, mysqld_pid_file_path gibt den Pfad zur PID-Datei an -z string bestimmt, ob die Zeichenfolge leer ist Wenn basedir nicht explizit festgelegt ist, ist /usr/local/mysql der Standard. Aus diesem Grund empfehlen viele MySQL-Installationstutorials, MySQL-bezogene Dateien in /usr/local/mysql zu platzieren. Wenn datadir nicht explizit festgelegt ist, wird standardmäßig $basedir/data verwendet. Definieren Sie die Funktionen log_success_msg() und log_failure_msg() Stellen Sie zunächst fest, ob die Datei /lib/lsb/init-functions vorhanden ist. Wenn ja, machen Sie alle in der Datei init-functions definierten Shell-Funktionen im aktuellen Skript wirksam. Wenn nicht, definieren Sie zwei Funktionen, eine zum Drucken der Erfolgsprotokolle und die andere zum Drucken der Fehlerprotokolle. In RHCS 6.7 existiert diese Datei nicht und wurde durch /etc/init.d/functions ersetzt. # # Verwenden Sie nach Möglichkeit LSB-Init-Skriptfunktionen zum Drucken von Nachrichten # lsb_functions="/lib/lsb/init-functions" wenn test -f $lsb_functions; dann . $lsb_funktionen anders log_success_msg() { echo " ERFOLGREICH! $@" } log_failure_msg() { echo " FEHLER! $@" } fi Übergeben von Parametern Übergeben Sie das erste Argument an mode und die restlichen Argumente an other_args PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin" Exportpfad mode=$1 # starten oder stoppen [ $# -ge 1 ] && verschieben other_args="$*" # ungewöhnlich, aber erforderlich, wenn es von einer RPM-Upgrade-Aktion aufgerufen wird # Erwartet: „--skip-networking --skip-grant-tables“ # Sie werden hier absichtlich nicht überprüft, da es in der Verantwortung liegt # des Autors der „spec“-Datei, um nur korrekte Argumente anzugeben. Fall `echo "testing\c"`, `echo -n testing` in *c*,-n*) echo_n= echo_c= ;; *c*,*) echo_n=-n echo_c= ;; *) echo_n= echo_c='\c' ;; esac Parameter in Konfigurationsdateien analysieren Auf diese Funktion wird später im Skript verwiesen. Die wichtigsten beteiligten Parameter sind: --basedir, --datadir, --pid-file, --service-startup-timeout. parse_server_arguments() { für arg tun Fall "$arg" in --basedir=*) basedir=`echo "$arg" | sed -e ‚s/^[^=]*=//‘` bindir="$basedir/bin" wenn test -z "$datadir_set"; dann Datenverzeichnis="$basedir/data" fi sbindir="$basedir/sbin" libexecdir="$basedir/libexec" ;; --datadir=*) datadir=`echo "$arg" | sed -e ‚s/^[^=]*=//‘` datadir_set=1 ;; --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e ‚s/^[^=]*=//‘` ;; --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e ‚s/^[^=]*=//'` ;; esac Erledigt } Bestimmen Sie den Speicherort von my_print_defaults Zunächst wird geprüft, ob die ausführbare Datei im Bin-Verzeichnis unter dem aktuellen Pfad vorhanden ist. Wenn nicht, wird geprüft, ob sie im Verzeichnis $bindir (normalerweise $basedir/bin) vorhanden ist. Wenn es immer noch nicht existiert, wird geprüft, ob /etc/my.cnf existiert und lesbar ist. Wenn ja, wird geprüft, ob der Parameter basedir in der Konfigurationsdatei angegeben ist. Wenn angegeben, übernehmen Sie den Wert des Parameters und ermitteln Sie, ob sich im Verzeichnis, das dem Wert entspricht, eine ausführbare Datei „bin/my_print_defaults“ befindet. Der letzte Schritt, wenn die Datei my_print_defaults nicht im obigen Verzeichnis gefunden wird, Setzen Sie print_defaults einfach auf „my_print_defaults“ und hoffen Sie, dass sich der Befehl in der aktuellen PATH-Umgebung befindet. # Argumente aus der Datei my.cnf abrufen, # die einzige Gruppe, die von nun an gelesen wird, ist [mysqld] wenn test -x ./bin/my_print_defaults Dann print_defaults="./bin/my_print_defaults" elif test -x $bindir/my_print_defaults Dann print_defaults="$bindir/meine_druck_defaults" elif test -x $bindir/mysql_print_defaults Dann print_defaults="$bindir/mysql_print_defaults" anders # Versuchen Sie, das Basisverzeichnis in /etc/my.cnf zu finden conf=/etc/meine.cnf drucken_standardwerte= wenn test -r $conf Dann subpat='^[^=]*basedir[^=]*=\(.*\)$' dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf` für d in $dirs Tun d=`echo $d | sed -e 's/[ ]//g'` wenn test -x "$d/bin/my_print_defaults" Dann print_defaults="$d/bin/meine_druck_defaults" brechen fi wenn test -x "$d/bin/mysql_print_defaults" Dann print_defaults="$d/bin/mysql_print_defaults" brechen fi Erledigt fi # Hoffe, es ist im PATH ... aber ich bezweifle es test -z "$print_defaults" && print_defaults="meine_print_defaults" fi Suchen der Standardkonfigurationsdatei -r Datei: Wahr, wenn die Datei lesbar ist # # Standarddatei aus 'basedir' lesen. Wenn dort keine Standarddatei vorhanden ist, # prüfen, ob es sich am alten (veralteten) Ort (datadir) befindet und von dort lesen # extra_args="" wenn test -r "$basedir/my.cnf" Dann extra_args="-e $basedir/my.cnf" anders wenn test -r "$datadir/my.cnf" Dann extra_args="-e $datadir/my.cnf" fi fi Parameter in Konfigurationsdateien analysieren Die Verwendung von my_print_defaults ist wie folgt: my_print_defaults --defaults-file=beispiel.cnf Client MySQL Das heißt, lesen Sie die Parameterkonfiguration der Client- und MySQL-Teile in der Konfigurationsdatei. Insbesondere werden in diesem Skript die Konfigurationsparameter von mysqld, server, mysql_server und mysql.server gelesen. parse_server_arguments `$print_defaults $extra_args mysqld-Server mysql_server mysql.server` Legen Sie den Pfad zur PID-Datei fest -z string bestimmt, ob die Zeichenfolge leer ist Wenn --pid-file in der gelesenen Konfigurationsdatei nicht gesetzt ist oder der Parameter mysqld_pid_file_path am Anfang des Skripts nicht gesetzt ist, Die PID-Datei wird standardmäßig unter Datadir festgelegt und trägt den Namen hostname.pid. Wenn dieser Parameter gesetzt ist, ist eine weitere Beurteilung erforderlich Wenn dieser Parameter einen Schrägstrich enthält, bedeutet dies, dass der angegebene Wert einen Pfad hat und direkt verwendet werden kann. Wenn in diesem Parameter kein Pfad vorhanden ist, bedeutet dies, dass der angegebene Wert lediglich der Dateiname der PID ist, der unter Datadir festgelegt werden kann. # # PID-Datei festlegen, falls nicht angegeben # wenn test -z "$mysqld_pid_file_path" Dann mysqld_pid_file_path=$datadir/`hostname`.pid anders Fall "$mysqld_pid_file_path" in /* ) ;; * )mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;; esac fi Startoptionen für Serviceskripte Wechseln Sie zunächst zu $basedir Stellen Sie zweitens fest, ob mysqld_safe in $basedir/bin eine ausführbare Datei ist. Wenn ja, starten Sie die mysqld-Instanz. Wenn nicht, melden Sie einen Fehler und beenden Sie das Programm. Wie wird also der Startvorgang implementiert? Führen Sie zunächst den Befehl $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & aus, um die mysqld-Instanz zu starten. Ist Ihnen aufgefallen, dass mysqld_safe tatsächlich in basedir ausgeführt wird, einschließlich des MySQL-Initialisierungsskripts mysql_install_db, dessen Ausführung in basedir ebenfalls empfohlen wird? Weitere Einzelheiten finden Sie unter: Analysieren des MariaDB-Initialisierungsskripts mysql_install_db Anschließend wird die Funktion wait_for_pid zur Beurteilung verwendet. Einzelheiten finden Sie in der Analyse der Funktion wait_for_pid weiter unten. Nachdem das Urteil gefällt wurde, Überprüfen Sie, ob das Verzeichnis $lockdir beschreibbar ist. Wenn ja, erstellen Sie eine Datei im Verzeichnis. Fall "$mode" in 'Start') # Daemon starten # Absicherung (relative Pfade, Core Dumps...) cd $basedir echo $echo_n "MySQL wird gestartet" wenn test -x $bindir/mysqld_safe Dann # Geben Sie mysqld zusätzliche Argumente mit der Datei my.cnf. Dieses Skript # kann beim nächsten Upgrade überschrieben werden. $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & wait_for_pid hat "$!" erstellt "$mysqld_pid_file_path"; Rückgabewert=$? # Sperre für RedHat / SuSE erstellen wenn test -w "$lockdir" Dann berühren Sie "$lock_file_path" fi beenden $return_value anders log_failure_msg "MySQL-Server konnte nicht gefunden werden ($bindir/mysqld_safe)" fi ;; wait_for_pid-Funktion Nach dem Starten der MySQL-Instanz mit mysqld_safe wird dieser Parameter aufgerufen wait_for_pid hat "$!" erstellt "$mysqld_pid_file_path"; Rückgabewert=$? $! wird in der Shell verwendet, um die PID des zuletzt ausgeführten Hintergrundprozesses abzurufen. In diesem Fall ist es die PID des mysqld_safe-Prozesses. Da der erste Parameter erstellt wird, wird -s Datei Wahr, wenn die Dateilänge ungleich Null ist Dieser Befehl bewirkt, dass, wenn die PID-Datei existiert, die Variable i auf leer gesetzt und die While-Schleife verlassen wird. Führen Sie dann das folgende Urteil durch: wenn test -z "$i" ; dann log_erfolg_msg Rückgabe 0 anders log_failure_msg Rückgabe 1 fi Wenn $i leer ist, wird das Erfolgsprotokoll gedruckt und das Skript beendet. Wenn die PID-Datei vorhanden ist, wird die Variable i natürlich auf leer gesetzt. Schauen wir uns die Situation an, in der die PID-Datei nicht existiert Zuerst wird geprüft, ob $pid nicht leer ist (d. h. wenn test -n "$pid") Wenn es nicht leer ist, bedeutet dies, dass die PID des Prozesses nach der Ausführung von mysqld_safe erfasst wurde. Bestätigen Sie in diesem Fall zusätzlich, ob der Prozess existiert, indem Sie kill -0 "$pid" verwenden. kill -0 sendet kein Signal, aber das System führt eine Fehlerprüfung durch. Daher wird es häufig verwendet, um zu prüfen, ob ein Prozess vorhanden ist. Wenn der Prozess nicht vorhanden ist, gibt kill -0 pid einen Fehler zurück. Wenn der Prozess existiert, wird keine Operation ausgeführt und die folgende Operation direkt übersprungen. echo $echo_n ".$echo_c" i=`Ausdruck $i + 1` Schlaf 1 Erhöhen Sie die Variable i um 1 und schlafen Sie 1 Sekunde lang. Setzen Sie dann die while-Schleife fort. Der Grund hierfür ist, dass mysqld_safe ausgeführt wurde, die mysqld-Instanz sich jedoch noch im Startvorgang befindet und die PID-Datei noch nicht erstellt wurde. Bis $1 die durch $service_startup_timeout definierte Dauer erreicht. Wenn Sie während der while-Schleife mit kill -0 "$pid" feststellen, dass der Prozess nicht mehr existiert, Es wird erneut beurteilt. Wenn das Ergebnis dieser Beurteilung immer noch ist, dass die PID-Datei nicht existiert und der Prozess nicht existiert, wird es ausgeführt log_failure_msg "Der Server wurde beendet, ohne die PID-Datei ($pid_file_path) zu aktualisieren." Dies ist der Ursprung des berühmten „Der Server wurde beendet, ohne die PID-Datei zu aktualisieren.“ warte_auf_pid () { verb="$1" # erstellt | entfernt pid="$2" # Prozess-ID des Programms, das die PID-Datei bearbeitet pid_file_path="$3" # Pfad zur PID-Datei. ich = 0 avoid_race_condition="durch erneute Prüfung" während Test $i -ne $service_startup_timeout; mache Fall "$verb" in 'erstellt') # Warten Sie, bis eine PID-Datei erstellt wird. test -s "$pid_file_path" && i='' && break ;; 'ENTFERNT') # warten, bis diese PID-Datei verschwindet Prüfung! -s "$pid_file_path" && i='' && break ;; *) echo "wait_for_pid () Verwendung: wait_for_pid erstellt|entfernt pid pid_file_path" Ausfahrt 1 ;; esac # wenn der Server nicht läuft, wird die PID-Datei nie aktualisiert wenn test -n "$pid"; dann wenn kill -0 "$pid" 2>/dev/null; dann : # der Server läuft noch anders # Der Server wurde möglicherweise zwischen der letzten PID-Dateiprüfung und jetzt beendet. wenn test -n "$avoid_race_condition"; dann race_condition vermeiden="" weiter # Nochmals prüfen. fi # es gibt nichts, was die Datei beeinflussen würde. log_failure_msg "Der Server wurde beendet, ohne die PID-Datei ($pid_file_path) zu aktualisieren." return 1 # nicht mehr warten. fi fi echo $echo_n ".$echo_c" i=`Ausdruck $i + 1` Schlaf 1 Erledigt wenn test -z "$i" ; dann log_erfolg_msg Rückgabe 0 anders log_failure_msg Rückgabe 1 fi } Option zum Stoppen des Serviceskripts Stellen Sie zunächst fest, ob die Länge der PID-Datei ungleich Null ist. -s Datei Wahr, wenn die Dateilänge ungleich Null ist An diesem Punkt wird die PID des mysqld-Prozesses über die PID-Datei abgerufen. Beachten Sie, dass es sich nicht um die PID des mysqld_safe-Prozesses handelt. Stellen Sie dann fest, ob der mysqld-Prozess normal ausgeführt wird. Wenn ja, beenden Sie den mysqld-Prozess, indem Sie $mysqld_pid beenden. Der sicherste Weg, einen Prozess zu beenden, ist die einfache Verwendung des Kill-Befehls ohne Modifikatoren oder Flags. Der Standardbefehl „Kill“ beendet normalerweise den problematischen Prozess und gibt die Ressourcen des Prozesses für das System frei. Wenn der Prozess jedoch untergeordnete Prozesse gestartet hat, reicht es aus, den übergeordneten Prozess zu beenden, damit die untergeordneten Prozesse weiter ausgeführt werden und somit weiterhin Ressourcen verbrauchen. Um diese sogenannten „Zombie-Prozesse“ zu verhindern, achten Sie darauf, alle untergeordneten Prozesse zu beenden, bevor Sie den übergeordneten Prozess beenden. Anschließend wird die Funktion wait_for_pid aufgerufen, um eine Entscheidung zu treffen. Tatsächlich dient das Setzen der Variable avoid_race_condition in der Funktion wait_for_pid der Stoppoption. Es ist tatsächlich möglich, dass mysqld nach der Überprüfung der PID-Datei und vor der Überprüfung, ob der Prozess aktiv ist, beendet wird. Wenn der mysqld-Prozess nicht ordnungsgemäß läuft, wird die Meldung „MySQL-Serverprozess #$mysqld_pid läuft nicht!“ ausgegeben und die PID-Datei wird gelöscht. Wenn die Länge der PID-Datei beim Ausführen von „Stop“ 0 ist, wird die Meldung „Die PID-Datei des MySQL-Servers konnte nicht gefunden werden!“ ausgegeben. Wenn die PID-Datei nicht existiert, wird der mysqld-Prozess daher nicht beendet, wenn die Stoppoption über das Serviceskript ausgeführt wird. Zu diesem Zeitpunkt können Sie den mysqld-Prozess beenden, indem Sie $mysqld_pid beenden. 'stoppen') # Daemon stoppen. Wir verwenden hier ein Signal, um nicht wissen zu müssen, # Root-Passwort. wenn test -s "$mysqld_pid_file_path" Dann mysqld_pid=`cat "$mysqld_pid_Dateipfad"` wenn (kill -0 $mysqld_pid 2>/dev/null) Dann echo $echo_n "MySQL wird heruntergefahren" Beenden Sie $mysqld_pid # mysqld sollte die PID-Datei beim Beenden entfernen, warten Sie also darauf. wait_for_pid hat "$mysqld_pid" "$mysqld_pid_file_path" entfernt; Rückgabewert=$? anders log_failure_msg "MySQL-Serverprozess #$mysqld_pid läuft nicht!" rm "$mysqld_pid_dateipfad" fi # Sperre für RedHat / SuSE löschen wenn test -f "$lock_file_path" Dann rm -f "$lock_file_pfad" fi beenden $return_value anders log_failure_msg "MySQL-Server-PID-Datei konnte nicht gefunden werden!" fi ;; Option zum Neustarten des Dienstskripts Führen Sie zuerst den Stoppvorgang aus. Wenn der Stoppvorgang erfolgreich ist, führen Sie den Startvorgang weiter aus. Wenn der Stoppvorgang fehlschlägt, wird die Meldung „Der laufende Server konnte nicht gestoppt werden, daher wird der Startversuch verweigert.“ ausgegeben und das Skript wird beendet. 'Neustart') # Stoppen Sie den Dienst und unabhängig davon, ob er # läuft oder nicht, starten Sie es erneut. wenn $0, stopp $other_args; dann $0 Start $andere_args anders log_failure_msg "Der laufende Server konnte nicht gestoppt werden. Daher wird ein Startversuch abgelehnt." Ausfahrt 1 fi ;; Optionen zum Neuladen des Serviceskripts Bestimmen Sie zunächst, ob die Länge der PID-Datei 0 ist. Wenn nicht, setzen Sie den Wert in der Datei auf den Wert der Variablen mysqld_pid. Führen Sie dann die Operation kill -HUP für den Prozess aus. töten -HUP pid pid ist die Prozess-ID. Verwenden Sie diesen Befehl, wenn Sie die Konfiguration ändern möchten, ohne den Dienst zu stoppen und neu zu starten. Nachdem Sie die erforderlichen Änderungen an den Konfigurationsdateien vorgenommen haben, geben Sie diesen Befehl ein, um die Dienstkonfiguration dynamisch zu aktualisieren. Wenn Sie ein Auflegesignal (Signal 1 oder HUP) senden, werden die meisten Serverprozesse (alle normalen Prozesse) standardmäßig zurückgesetzt und ihre Konfigurationsdateien neu geladen. Wenn die Länge der PID-Datei 0 ist, wird „MySQL PID-Datei konnte nicht gefunden werden!“ ausgegeben. 'neu laden'|'erzwungenes Neuladen') wenn test -s "$mysqld_pid_file_path" ; dann mysqld_pid lesen < "$mysqld_pid_file_path" kill -HUP $mysqld_pid && log_success_msg "MySQL-Dienst wird neu geladen" berühren Sie "$mysqld_pid_file_path" anders log_failure_msg "MySQL PID-Datei konnte nicht gefunden werden!" Ausfahrt 1 fi ;; Option „Dienstskriptstatus“ Bestimmen Sie zunächst, ob die Länge der PID-Datei 0 ist. Wenn nicht, lesen Sie den Wert in der Datei und bestimmen Sie, ob der der PID entsprechende Prozess normal ausgeführt wird. Wenn es normal läuft, wird „MySQL läuft“ ausgegeben. Wenn es nicht normal ist, lautet die Ausgabe „MySQL läuft nicht, aber die PID-Datei ist vorhanden“ Wenn die Länge der PID-Datei 0 ist, versuchen Sie, ihre PID über den Startbefehl mysqld abzurufen. Zu diesem Zeitpunkt gibt es möglicherweise ein MySQLD-Programm, das mehrere Instanzen startet, was dazu führt, dass pid_count=`echo $mysqld_pid | wc -w` größer als 1 ist. Zu diesem Zeitpunkt wird die Meldung „Mehrere MySQL werden ausgeführt, aber die PID-Datei konnte nicht gefunden werden“ ausgegeben und das Skript wird beendet. Wenn mysqld_pid leer ist, wird weiter geprüft, ob "$lock_file_path" existiert. Wenn ja, Es wird die Meldung „MySQL läuft nicht, aber die Sperrdatei ($lock_file_path) ist vorhanden“ ausgegeben. Wenn "$lock_file_path" nicht existiert, wird die Meldung "MySQL läuft nicht" ausgegeben. Wenn mysqld_pid gleich 1 ist, wird die Meldung „MySQL läuft, aber die PID-Datei konnte nicht gefunden werden“ ausgegeben. 'Status') # Überprüfen Sie zunächst, ob die PID-Datei vorhanden ist wenn test -s "$mysqld_pid_file_path" ; dann mysqld_pid lesen < "$mysqld_pid_file_path" wenn kill -0 $mysqld_pid 2>/dev/null; dann log_success_msg "MySQL läuft ($mysqld_pid)" Ausfahrt 0 anders log_failure_msg "MySQL läuft nicht, aber die PID-Datei existiert" Ausfahrt 1 fi anders # Versuchen Sie, den passenden mysqld-Prozess zu finden mysqld_pid=`pidof $libexecdir/mysqld` # testen, ob mehrere PIDs vorhanden sind pid_count=`echo $mysqld_pid | wc -w` wenn test $pid_count -gt 1; dann log_failure_msg "Mehrere MySQL laufen, aber die PID-Datei konnte nicht gefunden werden ($mysqld_pid)" Ausfahrt 5 elif test -z $mysqld_pid ; dann wenn test -f "$lock_file_path" ; dann log_failure_msg "MySQL läuft nicht, aber die Sperrdatei ($lock_file_path) existiert" Ausfahrt 2 fi log_failure_msg "MySQL läuft nicht" Ausfahrt 3 anders log_failure_msg „MySQL läuft, aber die PID-Datei konnte nicht gefunden werden“ Ausfahrt 4 fi fi ;; Andere Optionen für das Serviceskript Wenn das erste Argument des Skripts keine der oben genannten Optionen ist, werden Verwendungsinformationen ausgegeben. *) # Verwendung Basisname=`Basisname "$0"` echo "Verwendung: $basename {start|stop|restart|reload|force-reload|status} [MySQL-Serveroptionen]" Ausfahrt 1 ;; Zu diesem Zeitpunkt ist die Analyse des MySQL-Serviceskripts abgeschlossen ~ Zusammenfassen Beim Starten von MySQL über das Serviceskript wird der Fehler „Der Server wird beendet, ohne die PID-Datei zu aktualisieren“ gemeldet. Es gibt zwei Bedingungen Erstens existiert die PID-Datei nicht Überprüfen Sie zweitens, dass der Prozess nicht existiert, indem Sie -0 $pid beenden. Der Fehler kann derzeit nur über das Fehlerprotokoll der MySQL-Datenbank lokalisiert werden. Wenn das Serviceskript nicht angepasst ist, ist das Standard-Basedir /usr/local/mysql und das Datadir /usr/local/mysql/data Wenn Ihr MySQL-Dienst nicht im Standardpfad liegt, Sie müssen es explizit im Skript festlegen Nach dem Test sind folgende Einstellungen erforderlich: 1. Basedir festlegen und Conf-Variablen hinzufügen Hier bezieht sich conf auf die Konfigurationsdatei von mysqld. Es wird empfohlen, die Werte von basedir und datadir in der Konfigurationsdatei explizit anzugeben. Hier muss datadir nicht festgelegt werden, da datadir über die Konfigurationsdatei abgerufen werden kann. Aber basedir muss angegeben werden, da der Befehl my_print_deefauts zuerst nach basedir beurteilt werden muss basedir=/usr/local/mysql-advanced-5.6.23-linux-glibc2.5-x86_64 Datenverzeichnis= conf=/usr/local/mysql-advanced-5.6.23-linux-glibc2.5-x86_64/my_3308.cnf 2. Zeile 256, fügen Sie extra_args=" -c $conf" hinzu extra_args="-e $basedir/my.cnf.bak" wenn test -r "$basedir/my.cnf" Dann extra_args="-e $basedir/my.cnf" anders wenn test -r "$datadir/my.cnf" Dann extra_args="-e $datadir/my.cnf" fi fi extra_args="-c $conf" 3. Ändern Sie die Startparameter von mysqld_safe in Zeile 285 Wille $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & Geändert zu, $bindir/mysqld_safe --defaults-file="$conf" --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & Hauptsächlich wurde die Option --defaults-file hinzugefügt Oben finden Sie eine ausführliche Analyse der Gründe, warum beim Starten von MySQL der Fehler „Der Server wurde beendet, ohne die PID-Datei zu aktualisieren“ auftritt. Ich hoffe, dass dies für Sie hilfreich ist. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und ich werde Ihnen rechtzeitig antworten. Ich möchte auch allen für ihre Unterstützung der Website 123WORDPRESS.COM danken! Das könnte Sie auch interessieren:
|
<<: So richten Sie einen FTP-Server in CentOS7 ein
>>: Der Implementierungsprozess des langen Drückens zum Identifizieren des QR-Codes im WeChat-Applet
Während des Entwicklungsprozesses verwenden wir h...
Inhaltsverzeichnis Installieren Konfiguration Häu...
Erste: Code kopieren Der Code lautet wie folgt: &l...
Inhaltsverzeichnis Vorwort Vorbereiten Zusammenfa...
Tipp 1: Konzentriert bleiben Die besten mobilen A...
Inhaltsverzeichnis 1. Schritte 1. Definieren Sie ...
Befehl ausführen docker run -d --name consul -p 8...
Inhaltsverzeichnis 1. Projektkonstruktion 2. Vue3...
1. Einführung in Varnish Varnish ist ein leistung...
Ich habe erst vor Kurzem angefangen, mich mit Dat...
Finden Sie das Problem Heute werde ich den Tomcat...
Inhaltsverzeichnis Vorwort 1. Vorschau der Office...
Inhaltsverzeichnis Vorwort 1. Routing von Lazy Lo...
1. Online-Textgenerator BlindTextGenerator: Für D...
CocosCreator Version 2.3.4 Drachenknochenanimatio...