Was verursacht das Warten auf Sperrfehler auf Tabellenebene?

8

Wir haben die Datenbank bereits zweimal hängen lassen und versucht, eine Ursache zu finden.

show processlist
Waiting for global read lock | INSERT INTO {myisam_table} ...

Hier war der Speicherplatz voll, so dass wir dachten, das Problem sei vorbei, nachdem wir ihm etwas mehr gegeben hatten, aber am nächsten Tag um die Mittagszeit hing es wieder:

show processlist
Waiting for table level lock | UPDATE {myisam_table} ... 

Was könnte es verursachen?

MySQL-Standard-Engine: InnoDB.

Die Datenbank enthält eine Mischung aus Tabellen mit MyISAM- und InnoDB-Engines.

Log hier gepostet:

http://arturito.net/2013/08/28/mysql-waiting-for-table-level-lock-errors/

Artur Kędzior
quelle
Die beiden Ereignisse können nicht miteinander zusammenhängen, da Sie sagen, dass Sie gleichzeitig ein Speicherplatzproblem hatten und da es sich um zwei verschiedene Arten von Sperren handelt, die möglicherweise durch nicht zusammenhängende Dinge verursacht wurden. Eine Möglichkeit, die beide verursacht haben könnte, ist ein Backup mit mysqldump. Haben Sie zu diesem Zeitpunkt ein Backup ausgeführt?
Michael - sqlbot
Alle Backups werden um 7:00 Uhr beendet und niemals während der Arbeitszeit ausgeführt. Die Datenbank blieb zur Mittagszeit hängen.
Artur Kędzior
Wenn eine MyISAM-Tabelle in einer DB-Sitzung gesperrt ist, muss eine andere DB-Sitzung vorhanden sein, die sie gesperrt hat. Bitte zeigen Sie beim nächsten Mal die vollständige Prozessliste.
RolandoMySQLDBA
@Arturito brauchen wir wahrscheinlich SHOW FULL PROCESSLISTeher, als SHOW PROCESSLISTdass wir die gesamte Abfrage für jeden Thread sehen können ... aber so wie es jetzt MyISAMaussieht , wenn es sich um Tabellen handelt, sieht es so aus, als ob die lang laufende SELECTAbfrage in 42686 die UPDATEAbfrage in 43506 blockiert Dies blockiert wiederum jede SELECTdarauf folgende Abfrage.
Michael - sqlbot

Antworten:

8

ERSTE BEMERKUNGEN

  • Die Prozess-ID 42686 bereitet die Ausführung einer SELECT-Abfrage vor
  • Es gibt einige Schlafverbindungen
  • Alle anderen Prozesse können keine Tabellensperre erhalten
  • Ich hätte erwartet, dass ein UPDATE, DELETE oder INSERT die Sperre durchführt. Es besteht kein Anspruch auf Eigentum an der betreffenden Tabelle.
  • Kann nicht die vollständige Abfrage in Prozess - ID siehe 42686, aber ich vermute , es handelt JOIN, GROUP BYoderORDER BY

ARBEITSTHEORIE

Wenn Ihnen mit der von Ihnen angegebenen Prozessliste der Speicherplatz ausgeht, können wir die MyISAM-Speicher-Engine dafür verantwortlich machen. Warum?

In Ihrem speziellen Fall ist es nicht eine Ihrer Tabellen. Wenn a JOIN, GROUP BYoder ORDER BYausgeführt wurde und eine temporäre Tabelle auf die Festplatte geschrieben wurde (auf temporären Datenträgertabellen wird die MyISAM-Speicher-Engine verwendet), friert MySQL einfach ein, wenn nicht genügend Speicherplatz vorhanden ist. Woher weiß ich das ?

Gemäß MySQL 5.0 Certification Study Guide

Geben Sie hier die Bildbeschreibung ein In Abschnitt 29.2 Bulletpoint 11 heißt es:

Wenn Ihnen beim Hinzufügen von Zeilen zu einer MyISAM-Tabelle nicht genügend Speicherplatz zur Verfügung steht, tritt kein Fehler auf. Der Server unterbricht den Vorgang, bis Speicherplatz verfügbar ist, und schließt den Vorgang dann ab.

Ich habe diese Situation schon einmal besprochen

Etwas sagt mir, dass Sie eine dieser beiden Situationen haben

  • festplattenbasierte temporäre Tabellen für Ihre SELECTs und Konkurrenz um Speicherplatz mit Ihren regulären Daten
  • Wenn temporäre Tabellen /tmpin der Root-Partition landen , ist der Speicherplatz knapp

VORSCHLÄGE

Vorschlag 1: Ordnen Sie tmpdir einer anderen Festplatte zu

[mysqld]
tmpdir = /another/disk/besides/root/partition

Vorschlag 2: Erstellen Sie eine RAM-Disk

Führen Sie diesen Code aus, um eine RAM-Disk zu installieren, die beim Linux-Neustart verfügbar ist.

RAMDISK_SIZE=32g
service mysql stop
mkdir /var/tmpfs
echo "none   /var/tmpfs  tmpfs  defaults,size=${RAMDISK_SIZE} 1 2" >> /etc/fstab
mount -t tmpfs -o size=${RAMDISK_SIZE} none /var/tmpfs
cp -R /var/lib/mysql/* /var/tmpfs
mv /var/lib/mysql /var/lib/mysql_old
ln -s /var/tmpfs /var/lib/mysql
chown -R mysql:mysql /var/tmpfs
chown -R mysql:mysql /var/lib/mysql
service mysql start

Ordnen Sie dann tmpdir zu/var/tmpfs

VERSUCHE ES !!!

RolandoMySQLDBA
quelle
Ein guter Rat für RAM Disk - große Geschwindigkeitsgewinne, dafür benötigen Sie viel Speicher - ist wie eine SSD.
Up_One