Wie kann man MySQL richtig töten?


28

Ich habe CentOS 64bit mit CPanel installiert und benutze:

service mysql stop

Es tickt einfach weiter und scheint nie anzuhalten. In den Protokollen werden nur viele Einträge gepostet:

130303 17:42:38 [Warning] /usr/sbin/mysqld: Forcing close of thread

In der err.logDatei sehe ich viele davon:

[Warning] /usr/sbin/mysqld: Forcing close of thread

Früher war es augenblicklich. Irgendeine Idee, warum es das macht und wie man es repariert?

Im Moment muss ich tun, killall -9 mysqlaber gibt es einen besseren Weg?

Der Server ist auch sehr sehr aktiv.

Ist das ein Konfigurationsproblem? Habe ich zu hohe Speichereinstellungen?

[mysqld]
default-storage-engine=MyISAM
local-infile=0
symbolic-links=0
skip-networking
max_connections = 500
max_user_connections = 20
key_buffer = 512M
myisam_sort_buffer_size = 64M
join_buffer_size = 64M
read_buffer_size = 12M
sort_buffer_size = 12M
read_rnd_buffer_size = 12M
table_cache = 2048
thread_cache_size = 16K
wait_timeout = 30
connect_timeout = 15
tmp_table_size = 64M
max_heap_table_size = 64M
max_allowed_packet = 64M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 64M
query_cache_type = 1
low_priority_updates=1
concurrent_insert=ALWAYS
log-error=/var/log/mysql/error.log
tmpdir=/home/mysqltmp
myisam_repair_threads=4
[mysqld_safe]
open_files_limit = 8192
log-error=/var/log/mysql/error.log

[mysqldump]
quick
max_allowed_packet = 512M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

Antworten:


37

Der einfachste Weg, um mysql herunterzufahren, ist das Ausführen

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Hier ist warum:

Die mysql-Service-Datei ( /etc/init.d/mysql) setzt das Vorhandensein der Socket-Datei voraus. Historisch gesehen verschwindet die Socket-Datei manchmal aus unerklärlichen Gründen. Dies behindert einen Standard service mysql stopbeim Arbeiten.

Es ist nicht genug zu sagen

mysqladmin -uroot -p -h127.0.0.1 shutdown

weil mysqld einen Benutzer dahingehend weiterleitet root@127.0.0.1, root@localhostob TCP / IP nicht explizit aktiviert ist. Standardmäßig mysqld den Weg des geringsten Widerstands wählen und eine Verbindung root@127.0.0.1zu root@localhostüber die Socket - Datei. Wenn jedoch keine Socket-Datei vorhanden ist, root@localhostwird keine Verbindung hergestellt.

Sogar in der MySQL-Dokumentation zu mysqladmin heißt es:

Wenn Sie mysqladmin shutdown ausführen, wenn Sie eine Verbindung zu einem lokalen Server mithilfe einer Unix-Socket-Datei herstellen, wartet mysqladmin, bis die Prozess-ID-Datei des Servers entfernt wurde, um sicherzustellen, dass der Server ordnungsgemäß gestoppt wurde.

Aus diesem Grund muss TCP / IP unbedingt aktiviert werden:

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Zurück am 30. September 2011 habe ich meine eigene Version von mysqld_multicalled geschrieben mysqlservice(siehe meinen Beitrag: Mehrere Instanzen auf demselben Host ausführen ). Es dient als virtuelle Engine zum Herstellen einer Verbindung zu mysqld über verschiedene Ports. Sie müssen nur Ihre eigenen my.cnfParameter mitbringen . In diesem Skript stelle ich Shutdowns wie folgt aus:

stop() {
  ${ECHO} -n $"Stopping ${PROGNAME}"
  ${MYSQLD_STOP}
  ATTEMPTS=0
  STOPPING_MYSQLD=1
  MINUTES_TO_TRY=10
  (( TICKS_TO_TRY = MINUTES_TO_TRY*240 ))
  while [ ${STOPPING_MYSQLD} -eq 1 ]
  do
    ${ECHO} -n "."
    ${SLEEP} 0.25
    MYSQLD_HAS_BEEN_SHUTDOWN=`${TAIL} ${MYSQL_ERROR_LOG} | ${GREP} -c "Shutdown complete$"`
    (( ATTEMPTS++ ))
    if [ ${ATTEMPTS} -eq ${TICKS_TO_TRY}   ] ; then STOPPING_MYSQLD=0 ; fi
    if [ ${MYSQLD_HAS_BEEN_SHUTDOWN} -eq 1 ] ; then STOPPING_MYSQLD=2 ; fi
  done
  ${ECHO}
  if [ ${STOPPING_MYSQLD} -eq 2 ]
  then
    ${ECHO} "Stopped ${PROGNAME}"
  else
    ${TAIL} -30 ${MYSQL_ERROR_LOG}
  fi
}

Aber was ist ${MYSQLD_STOP}?

MYSQL_CONN="-uroot -p<rootpassword> -P${MYSQLD_PORT} -h127.0.0.1 --protocol=tcp"
MYSQLD_STOP="${MYSQLADMIN} ${MYSQL_CONN} shutdown"

Bitte beachte, dass ich 127.0.0.1einen expliziten Port verwende. Auf diese Weise verlasse ich mich nicht auf eine Socket-Datei.

Ich habe immer mysqladmin --protocol=tcp shtudownals die richtige Alternative zum Herunterfahren von MySQL verwendet, wenn es service mysql stophängt. Tun kill -9auf mysqldund mysqld_safesollte die letzte der letzten der letzten Resorts. (Ja, das habe ich zuletzt dreimal gesagt).

Oft hat mysqld mysql.sock ohne Vorwarnung gelöscht. Dieses Problem hatten im Laufe der Jahre auch andere Menschen:

EPILOG

Das Geheimnis ist wie gesagt: Mit mysqladmin über TCP / IP ( --protocol=tcp) mit mysql verbinden und ausgeben shutdown. Dies hat zu arbeiten , weil das Herunterfahren Privileg in ist mysql.userfür den ausschließlichen Zweck der authentifizierten Abschaltungen. Dies hat meinen Arbeitstag ein paar Mal gespart, als ich in der Lage war, einen Remote-Shutdown von meinem Windows-Computer aus durchzuführen, wenn mysqld auf einem Linux-Server heruntergefahren wurde.

UPDATE 06.03.2013 22:48 EST

Wenn Sie sich Sorgen darüber machen, was während des Herunterfahrens vor sich geht, können Sie die Herunterfahrzeit und die Art und Weise, in der die Daten auf die Festplatte geschrieben werden, ändern, insbesondere, wenn sich viele InnoDB-Daten im Pufferpool befinden

VORSCHLAG # 1

Wenn Sie viele schmutzige Seiten haben, können Sie den Wert für innodb_max_dirty_pages_pct auf 0 senken :

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Stellen Sie dies ca. 15-30 Minuten vor dem Herunterfahren ein. Dadurch erhält mysqld die geringstmögliche Menge an schmutzigen Seiten, die auf die Festplatte geschrieben werden können.

VORSCHLAG # 2

Standardmäßig ist innodb_fast_shutdown 1. Für diese Option gibt es drei Werte

  • 0: InnoDB führt vor dem Herunterfahren ein langsames Herunterfahren, eine vollständige Bereinigung und einen Einfügepuffer durch.
  • 1: InnoDB überspringt diese Vorgänge beim Herunterfahren. Dieser Vorgang wird als schnelles Herunterfahren bezeichnet.
  • 2: InnoDB löscht seine Protokolle und fährt kalt herunter, als ob MySQL abgestürzt wäre. Es gehen keine festgeschriebenen Transaktionen verloren, aber die Wiederherstellung nach einem Absturz führt dazu, dass der nächste Start länger dauert.

Die Dokumentation sagt weiter folgendes:

Das langsame Herunterfahren kann Minuten oder sogar Stunden in extremen Fällen dauern, in denen noch erhebliche Datenmengen gepuffert sind. Verwenden Sie die Slow-Shutdown-Technik, bevor Sie ein Upgrade oder Downgrade zwischen Hauptversionen von MySQL durchführen, damit alle Datendateien vollständig vorbereitet sind, falls der Upgrade-Prozess das Dateiformat aktualisiert.

Verwenden Sie innodb_fast_shutdown = 2 in Notfallsituationen oder zur Fehlerbehebung, um das absolut schnellste Herunterfahren zu erhalten, wenn das Risiko besteht, dass Daten beschädigt werden.

Die Standardeinstellungen für innodb_max_dirty_pages_pct und innodb_fast_shutdown sollten in den meisten Fällen in Ordnung sein.


2
Die Socket-Datei verschwindet bei Red Hat-Derivaten, da tmpwatchsie zusammen mit /tmpallen anderen Elementen gelöscht wird, deren Zeitpunkt älter als der konfigurierte Schwellenwert ist.
Michael - sqlbot

Danke, @ Michael-sqlbot Ich musste das endlich von jemandem hören. Ich denke, deshalb hat sich jemand bei MySQL AB (vor Oracle, vor Sun) entschieden, das SHUTDOWN-Privileg hinzuzufügen, um solche mysql.userKopfschmerzen zu umgehen .
RolandoMySQLDBA

Unter Verwendung von Debian oder Ubuntu mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown... enthält diese Datei Anmeldeinformationen für ein root-ähnliches MySQL-Konto.
0xC0000022L

Wie üblich, @RolandoMySQLDBA, sind Sie eine der besten DBA-Ressourcen auf den Stack Exchange-Sites. Tolle Arbeit hier, die mir über 6 Jahre später geholfen hat.
JakeGould

5

Es hört sich so an, als würde Ihre Frage weniger danach lauten, wie MySQL heruntergefahren wird, als vielmehr, warum MySQL so langsam heruntergefahren wird.

In meiner Antwort auf eine ähnliche Frage habe ich einige Vorschläge für einen reibungslosen Neustart gegeben, die dazu beitragen, dass weniger Aktivitäten ausgeführt werden müssen, nachdem Sie MySQL aufgefordert haben, mit dem Herunterfahren zu beginnen .

Wenn Sie SHOW FULL PROCESSLIST;dieses Element nicht häufig verwenden , müssen Sie wissen, was auf Ihrem Server vor sich geht, was das Herunterfahren so langsam macht. Wenn es lange laufende Abfragen gibt, die sicher zu unterbrechen sind, können Sie sie mit töten KILL <thread-id>.

Wiederholen Sie die anderen Vorschläge:

Das Setzen der globalen Variablen innodb_fast_shutdown = 1(Standard) beschleunigt InnoDB beim Herunterfahren. Dies ist jedoch nur dann sicher, wenn Sie den Server aus Gründen herunterfahren, die nichts mit der Durchführung eines Upgrades zu tun haben. Wenn Sie für ein Upgrade herunterfahren, muss dies auf 0 gesetzt werden.

Durch die FLUSH TABLES;ordnungsgemäße Verwendung werden alle geöffneten Tabellen geschlossen. Sie werden erneut geöffnet, wenn bei nachfolgenden Abfragen darauf verwiesen wird. Diese Aktion sollte jedoch die Zeitspanne zwischen der Anforderung des Herunterfahrens und dem Abschluss des Herunterfahrens verkürzen, da sie eine frühzeitige Reinigung durchführt und, was noch wichtiger ist, die Bühne bereitet für den letzten Schritt ...

FLUSH TABLES WITH READ LOCK;Schließt alle offenen Tabellen und ruft eine exklusive Sperre ab, die Ihrer aktuellen Client-Verbindung gehört und verhindert, dass eine andere Verbindung in eine Tabelle auf dem gesamten Server schreibt. Sie erhalten Ihre mysql>Aufforderung erst dann zurück, wenn Sie Eigentümer dieser Sperre sind. An diesem Punkt können Sie die Anforderung zum Herunterfahren absetzen. Trennen Sie jedoch nicht die Verbindung zu dieser Sitzung.

Auf einem ausgelasteten Server sollten diese Schritte das Aktivitätsniveau auf dem Server verringern, die Situation erheblich leiser machen und dazu beitragen, dass das Herunterfahren oder der Neustart reibungsloser vonstatten geht.


2

Es ist wahrscheinlich, dass MySQL nicht nur gesperrt ist, sondern beim Herunterfahren Bereinigungsaktivitäten (Rollbacks usw.) ausführt. Wenn Sie dies beim Herunterfahren nicht zulassen, müssen Sie beim Starten häufig warten.

Beachten Sie Folgendes: Fahren Sie mysql in einem Terminalfenster herunter, während Sie das Fehlerprotokoll (tail -f [yourerror.log]) in einem anderen Terminalfenster anzeigen. Das Fehlerprotokoll zeigt Ihnen, was MySQL tut.


1

Es tut mir leid, von Ihren Erfahrungen zu hören, und ich hoffe, dass Ihnen meine Erfahrungen mit ähnlichen albernen MySQL-Szenarien weiterhelfen können.

Anstatt herauszufinden, wie Sie den MySQL-Dienst vom Server aus beenden können, müssen Sie in einigen Fällen den Zustand Ihres Systems wie folgt überprüfen, um festzustellen, ob ein Dienstmissbrauch vorliegt (die Annahme basiert auf dem Begriff für a CentOS / RHEL-Umgebung ):

 /usr/bin/iostat
 /usr/bin/uptime
 top -c

Verwenden Sie die folgenden Informationen, um die durchschnittliche Systemlast und die am häufigsten verwendeten Ressourcen im System zu ermitteln.

Sie müssen auch installieren mytop, um eine Gesamtübersicht über die vom System verarbeiteten SQL-Anweisungen zu erhalten.

Führen Sie zum Installieren mytopeinfach die folgenden Schritte aus:

 cd /root
 wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
 tar -zxvf /root/mytop-1.6.tar.gz
 cd /root/mytop-1.6
 perl Makefile.pl
 make
 make install
 chmod 644 /usr/local/bin/mytop
 vi /usr/local/bin/mytop 

(Verwenden Sie einen beliebigen Texteditor)

Suche nach "long|!" => \$config{long_nums},

Kommentiere es als #"long|!" => \$config{long_nums},

chmod 555 /usr/local/bin/mytop

Und du kannst gut mit mytop gehen . Überprüfen Sie damit die MySQL-Anweisungen, die Ihren MySQL-Dienst überlasten, und beenden Sie sie.

Die Ausführung der obigen Anweisungen bietet Ihnen die folgenden Möglichkeiten:

  • Diagnose des Status / Zustands Ihres Servers
  • Diagnose Ihrer Engpassursache

Sobald Sie die Ursache des Engpasses behoben haben, sollten Sie einen leichteren Tag haben, wenn Sie versuchen, den MySQL-Dienst neu zu starten. Ich hoffe, dass Sie die oben genannten Informationen nützlich finden.

Hinweis: mytop ist uralt und nicht gepflegt. Sie sollten wahrscheinlich innotopauf einem modernen System verwenden.


0

Die Standardimplementierung des Init-Skripts von MySQL signalisiert MySQL mit SIGTERM und wartet eine gewisse Zeit, bis MySQL heruntergefahren ist.

Nachdem MySQL ein SIGTERM erhalten hat, hört es zunächst auf, neue Verbindungen zu empfangen, und führt die noch ausstehenden Abfragen vollständig aus (dies kann je nach Arbeitslast und Anzahl der gleichzeitigen Clients eine Weile dauern) wiederum abhängig von Ihrer Arbeitsauslastung, Ihren Konfigurationen, dem verfügbaren Speicher und der Auswahl der Speicher-Engine. Nachdem alle Daten gelöscht wurden, wird MySQL den während der Initialisierungsphase zugewiesenen Speicher freigeben (dies kann auch eine Weile dauern, abhängig von der von MySQL zugewiesenen Speicherkapazität), alle noch geöffneten Datei-Handles schließen und dann aufrufen "exit (0)".

Wenn das Herunterfahren von MySQL nach der Aufforderung zum Herunterfahren viel Zeit in Anspruch nimmt, kann es durchaus sein, dass einer oder mehrere dieser Schritte viel Zeit in Anspruch nehmen. Wenn Sie Zeit haben, empfehle ich dringend, auf den Abschluss des Vorgangs zu warten (dies vermeidet Datenverlust oder lange Wiederherstellungsvorgänge, wenn Sie Ihre Datenbankinstanz erneut starten).

Leider enthält Ihre Frage nicht genügend Informationen, damit ich eine geeignete Lösung für Ihr Problem vorschlagen kann. Ich hoffe, das hilft, das Problem zu verstehen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.