MySQL ist eine gängige relationale Open-Source-Datenbank, die leistungsstarke Datenspeicherdienste bereitstellt. Bei der Back-End-Entwicklung treten
manchmal Leistungsengpässe auf. Manchmal sind diese Engpässe nicht auf die Anwendung selbst zurückzuführen, sondern auf die Datenbankebene.
Die Beherrschung einiger der zugrunde liegenden Prinzipien von MySQL wird uns also helfen, MySQL besser zu verstehen, Leistungsoptimierungen für MySQL durchzuführen und
leistungsstarke Back-End-Dienste zu entwickeln.
1. Das logische Framework von MySQL
Das logische Framework-Diagramm von MySQL ist wie folgt:
Die oberste Ebene ist die Verwaltung des Clients .
Hauptsächlich Verbindungsverarbeitung, Autorisierungsauthentifizierung, Sicherheit usw. MySQL unterhält auf dieser Ebene einen Thread-Pool, um Verbindungen von Clients zu verarbeiten. MySQL kann die Authentifizierung mit Benutzername und Passwort verwenden,
kann auch die SSL-basierte X.509-Zertifikatauthentifizierung verwenden.
Die zweite Ebene besteht aus drei Teilen : Abfragecache, Parser und Optimierer. Der Parser wird zum Parsen von SQL-Anweisungen verwendet, und der Optimierer optimiert die analysierten Anweisungen.
Bevor die Abfrage analysiert wird, überprüft der Server zunächst den Abfragecache. Wenn das entsprechende Abfrageergebnis darin gefunden werden kann, ist keine Abfrageanalyse, Optimierung usw. erforderlich, und das Abfrageergebnis wird angezeigt direkt zurückgegeben. Gespeicherte Prozeduren, Trigger, Ansichten usw. werden alle in dieser Ebene implementiert.
Die dritte Schicht ist die Speicher-Engine Die Speicher-Engine ist für das Speichern von Daten in MySQL, das Extrahieren von Daten, das Starten einer Transaktion usw. verantwortlich. Die Speicher-Engine kommuniziert mit der oberen Ebene über APIs. Diese APIs schirmen die Unterschiede zwischen verschiedenen Speicher-Engines ab und machen diese Unterschiede für den Abfrageprozess der oberen Ebene transparent. Die Speicher-Engine analysiert SQL nicht. Die am häufigsten verwendete Speicher-Engine für MySQL ist InnoDB.
2. Parallelitätskontrolle von MySQL
Wenn mehrere Threads gleichzeitig Daten verarbeiten, kann es zu Problemen bei der Parallelitätskontrolle kommen.
2-1. Lese-/Schreibsperre
Wenn mehrere Threads nur Daten lesen, können sie diese tatsächlich gemeinsam lesen, ohne sich gegenseitig zu beeinflussen Verwenden Sie „Read Lock“, auch Shared Lock genannt.
Threads, die Lesesperren erwerben, blockieren sich nicht gegenseitig und können gleichzeitig eine Ressource lesen.
Wenn ein Thread Daten schreiben muss, sollte er eine „Schreibsperre“ verwenden, auch exklusive Sperre genannt.
Schreibsperren blockieren andere Schreibsperren und Lesesperren, bis der Schreibvorgang abgeschlossen ist.
2-2. Sperrgranularität
Klären Sie zunächst ein Konzept: Je weniger Daten auf einer bestimmten Ressource gesperrt werden müssen, desto höher ist die Parallelität Je höher das System ist, desto höher ist es.
Aber das Sperren verbraucht auch Ressourcen. Wenn das System viel Zeit damit verbringt, Sperren zu verwalten, anstatt auf Daten zuzugreifen,
dann kann die Leistung des Systems beeinträchtigt sein.
Eine gute „Sperrstrategie“ besteht also darin, ein Gleichgewicht zwischen Sperraufwand und Datensicherheit zu finden.
Jede Speicher-Engine kann Ihre eigene Sperrstrategie und Sperre implementieren Granularität.
2-3. Tabellensperren und Zeilensperren
Tabellensperren sperren, wie der Name schon sagt, die gesamte Tabelle. Der Aufwand für die Tabellensperre ist relativ gering. Nach dem Hinzufügen einer Schreibsperre zur Tabelle werden alle Lese- und Schreibvorgänge anderer Benutzer für die Tabelle blockiert.
Obwohl die Speicher-Engine in MySQL eigene Sperren bereitstellen kann, verwendet MySQL manchmal Tabellensperren, z. B. Anweisungen wie ALTER TABLE.
Schreibsperren haben eine höhere Priorität als Lesesperren, daher kann eine Schreibsperranforderung an den Anfang der Lesesperrenwarteschlange eingefügt werden.
Das Sperren auf Zeilenebene sperrt die gesamte Zeile, was die gleichzeitige Verarbeitung weitestgehend unterstützen kann, aber der Aufwand für das Entsperren ist auch relativ hoch. Sperren auf Zeilenebene werden nur auf der Ebene der Speicher-Engine implementiert.
Alle Speicher-Engines implementieren Sperren auf Zeilenebene auf ihre eigene Weise.
3. MVCC
MVCC ist „Mehrversions-Parallelitätskontrolle“. Man kann davon ausgehen, dass MVCC eine Variante der Sperrung auf Zeilenebene ist, aber es vermeidet das Hinzufügen In vielen Fällen sind zusätzliche Sperren
daher kostengünstiger.
Mainstream-relationale Datenbanken implementieren alle MVCC, aber die Implementierungsmechanismen sind unterschiedlich. Tatsächlich verfügt MVCC nicht über einen einheitlichen Standard.
Aber die meisten von ihnen implementieren nicht blockierende Lesevorgänge und Schreibvorgänge sperren nur notwendige Zeilen.
MVCC stellt sicher, dass die in jeder Transaktion während der Ausführung angezeigten Daten konsistent sind.
Da jedoch verschiedene Transaktionen zu unterschiedlichen Zeiten beginnen, können die gleichzeitig angezeigten Daten für dieselbe Tabelle unterschiedlich sein.
Die InnoDB-Engine von MySQL wird implementiert, indem zwei versteckte Spalten hinter jeder Datensatzzeile gespeichert werden.
Einer speichert die Erstellungszeit der Zeile und der andere speichert die Ablaufzeit (oder Löschzeit) der Zeile.
Tatsächlich wird kein tatsächlicher Zeitstempel gespeichert, sondern eine „Systemversionsnummer“.
Jedes Mal, wenn eine Transaktion gestartet wird, wird die Systemversionsnummer erhöht. Wenn eine Transaktion gestartet wird, wird die Systemversionsnummer als Versionsnummer der Transaktion verwendet und zum Vergleich mit der Versionsnummer der abgefragten Zeile verwendet.
Im Folgenden wird erläutert, wie Versionsnummern in gängigen CRUD-Operationen funktionieren:
INSERT
Speichern Sie die aktuelle Systemversion als Zeilenversionsnummer
LÖSCHEN
Speichern Sie die aktuelle Systemversionsnummer in der „Löschversion“ dieser Datenzeile.
UPDATE
Fügen Sie eine neue Zeile mit Datensätzen ein, speichern Sie die aktuelle Systemversionsnummer als Navigationsversionsnummer und speichern Sie die aktuelle Systemversionsnummer in der „Löschversion“ der ursprünglichen Zeile.
SELECT
Findet nur Zeilen, deren Version älter als die aktuelle Transaktionsversion ist. Dadurch wird sichergestellt, dass die von der Transaktion gelesenen Zeilen entweder bereits vorhanden sind,
oder von der Transaktion selbst eingefügt oder geändert wurden. Die „Löschversion“ der Zeile
ist entweder undefiniert oder größer als die aktuelle Transaktionsversionsnummer. Dadurch wird sichergestellt, dass die von der Transaktion gelesenen Zeilen
nicht vor der Transaktion gelöscht wurden.
MVCC funktioniert nur unter den beiden Isolationsstufen REPEATABLE READ
und READ COMMITTED
, die anderen beiden Isolationsstufen können nicht funktionieren.
Weil READ UNCOMMITTED
immer die neuesten Daten liest und nicht die Datenzeilen, die mit der aktuellen Transaktionsversion übereinstimmen. Und SERIALIZABLE
sperrt alle gelesenen Zeilen.
Die oben genannten Fragen zur Parallelitätskontrolle sind für Sie zusammengestellt. Weitere verwandte Fragen finden Sie in den entsprechenden Tutorials auf der chinesischen PHP-Website.
Empfohlenes Video-Tutorial: https://www.php.cn/course/list/51/type/2.html
Das obige ist der detaillierte Inhalt vonPrinzip der MySQL-Parallelitätskontrolle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!