Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Leistungs-Spickzettel

MySQL ist umfangreich und hat viele Bereiche zum Optimieren und Anpassen für die gewünschte Leistung. Einige Änderungen können dynamisch durchgeführt werden, andere erfordern einen Neustart des Servers. Es ist ziemlich üblich, eine MySQL-Installation mit einer Standardkonfiguration zu finden, obwohl letztere aufgrund Ihrer Arbeitslast und Ihres Setups möglicherweise nicht per se geeignet ist.

Hier sind die Schlüsselbereiche von MySQL, die ich aus verschiedenen Expertenquellen in der MySQL-Welt entnommen habe, sowie unsere eigenen Erfahrungen hier bei Multiplenines. Dieser Blog würde als Ihr Spickzettel dienen, um die Leistung zu optimieren und Ihr MySQL wieder großartig zu machen :-)

Werfen wir einen Blick darauf, indem wir die wichtigsten Bereiche in MySQL skizzieren.

Systemvariablen

MySQL hat viele Variablen, die Sie ändern können. Einige Variablen sind dynamisch, was bedeutet, dass sie mit der SET-Anweisung gesetzt werden können. Andere erfordern einen Neustart des Servers, nachdem sie in der Konfigurationsdatei festgelegt wurden (z. B. /etc/my.cnf, etc/mysql/my.cnf). Ich werde jedoch die allgemeinen Dinge durchgehen, die ziemlich häufig angepasst werden müssen, um den Server zu optimieren.

sort_buffer_size

Diese Variable steuert, wie groß Ihr Filesort-Puffer ist, was bedeutet, dass immer dann, wenn eine Abfrage die Zeilen sortieren muss, der Wert dieser Variablen verwendet wird, um die Größe zu begrenzen, die zugewiesen werden muss. Beachten Sie, dass diese Variable pro Abfrage (oder pro Verbindung) verarbeitet wird, was bedeutet, dass es speicherhungrig wäre, wenn Sie diese höher einstellen und wenn Sie mehrere Verbindungen haben, die eine Sortierung Ihrer Zeilen erfordern. Sie können Ihre Anforderungen jedoch überwachen, indem Sie die globale Statusvariable Sort_merge_passes überprüfen. Wenn dieser Wert groß ist, sollten Sie den Wert der Systemvariablen sort_buffer_size erhöhen. Andernfalls nehmen Sie es bis zur moderaten Grenze, die Sie benötigen. Wenn Sie dies zu niedrig einstellen oder große Abfragen verarbeiten müssen, kann die Sortierung Ihrer Zeilen langsamer als erwartet sein, da die Daten nach dem Zufallsprinzip abgerufen werden, wenn Festplattentauchgänge durchgeführt werden. Dies kann zu Leistungseinbußen führen. Es ist jedoch am besten, Ihre Abfragen zu korrigieren. Andernfalls, wenn Ihre Anwendung darauf ausgelegt ist, große Abfragen abzurufen und eine Sortierung erfordert, ist es effizient, Tools zu verwenden, die das Abfrage-Caching wie Redis handhaben. Standardmäßig beträgt der aktuelle Wertesatz in MySQL 8.0 256 KiB. Stellen Sie dies nur dann entsprechend ein, wenn Sie Abfragen haben, die häufig sorts verwenden oder aufrufen.

read_buffer_size

Die MySQL-Dokumentation erwähnt, dass für jede Anfrage, die einen sequentiellen Scan einer Tabelle durchführt, ein Lesepuffer zugewiesen wird. Die Systemvariable read_buffer_size bestimmt die Puffergröße. Sie ist auch für MyISAM nützlich, aber diese Variable wirkt sich auch auf alle Speicher-Engines aus. Für MEMORY-Tabellen wird es verwendet, um die Speicherblockgröße zu bestimmen.

Grundsätzlich weist jeder Thread, der einen sequentiellen Scan für eine MyISAM-Tabelle durchführt, einen Puffer dieser Größe (in Bytes) für jede Tabelle zu, die er scannt. Dies gilt auch für alle Speicher-Engines (einschließlich InnoDB), daher ist es hilfreich für Abfragen, die Zeilen mit ORDER BY sortieren und ihre Indizes in einer temporären Datei zwischenspeichern. Wenn Sie viele sequenzielle Scans durchführen, Masseneinfügungen in Partitionstabellen durchführen, Ergebnisse verschachtelter Abfragen zwischenspeichern und dann den Wert erhöhen. Der Wert dieser Variablen sollte ein Vielfaches von 4 KB sein. Wenn er auf einen Wert eingestellt ist, der kein Vielfaches von 4 KB ist, wird sein Wert auf das nächste Vielfache von 4 KB abgerundet. Beachten Sie, dass die Einstellung auf einen höheren Wert einen großen Teil des Arbeitsspeichers Ihres Servers verbraucht. Ich schlage vor, dies nicht ohne angemessenes Benchmarking und Monitoring Ihrer Umgebung zu verwenden.

read_rnd_buffer_size

Diese Variable befasst sich mit dem Lesen von Zeilen aus einer MyISAM-Tabelle in sortierter Reihenfolge nach einer Schlüsselsortierungsoperation, die Zeilen werden durch diesen Puffer gelesen, um Festplattensuchen zu vermeiden. Die Dokumentation besagt, dass beim Lesen von Zeilen in einer beliebigen Reihenfolge oder aus einer MyISAM-Tabelle in sortierter Reihenfolge nach einer Schlüsselsortierungsoperation die Zeilen durch diesen Puffer gelesen werden (und durch diese Puffergröße bestimmt werden), um Festplattensuchen zu vermeiden. Wenn Sie die Variable auf einen großen Wert setzen, kann die Leistung von ORDER BY erheblich verbessert werden. Dies ist jedoch ein Puffer, der jedem Client zugewiesen wird, daher sollten Sie die globale Variable nicht auf einen großen Wert setzen. Ändern Sie stattdessen die Sitzungsvariable nur innerhalb der Clients, die große Abfragen ausführen müssen. Beachten Sie jedoch, dass dies für MariaDB nicht gilt, insbesondere bei der Nutzung von MRR. MariaDB verwendet mrr_buffer_size, während MySQL read_buffer_size read_rnd_buffer_size verwendet.

join_buffer_size

Standardmäßig ist der Wert 256K. Die Mindestgröße des Puffers, der für einfache Indexscans, Bereichsindexscans und Joins verwendet wird, die keine Indizes verwenden und daher vollständige Tabellenscans durchführen. Wird auch von der BKA-Optimierung verwendet (die standardmäßig deaktiviert ist). Erhöhen Sie den Wert, um schnellere vollständige Joins zu erhalten, wenn das Hinzufügen von Indizes nicht möglich ist. Eine Einschränkung kann jedoch zu Speicherproblemen führen, wenn Sie dies zu hoch einstellen. Denken Sie daran, dass für jeden vollständigen Join zwischen zwei Tabellen ein Join-Puffer zugewiesen wird. Für einen komplexen Join zwischen mehreren Tabellen, für die keine Indizes verwendet werden, sind möglicherweise mehrere Join-Puffer erforderlich. Belassen Sie am besten global niedrig und setzen Sie ihn in Sitzungen hoch (mithilfe der SET SESSION-Syntax), die große vollständige Joins erfordern. Auf 64-Bit-Plattformen kürzt Windows Werte über 4 GB mit einer Warnung auf 4 GB-1.

max_heap_table_size

Dies ist die maximale Größe in Byte für benutzerdefinierte MEMORY-Tabellen, die wachsen dürfen. Dies ist hilfreich, wenn Ihre Anwendung mit MEMORY-Speicher-Engine-Tabellen arbeitet. Das Festlegen der Variablen bei aktivem Server hat keine Auswirkung auf vorhandene Tabellen, es sei denn, sie werden neu erstellt oder geändert. Der kleinere von max_heap_table_size und tmp_table_size begrenzt auch interne In-Memory-Tabellen. Diese Variable steht auch in Verbindung mit tmp_table_size, um die Größe interner In-Memory-Tabellen zu begrenzen (dies unterscheidet sich von den explizit als Engine=MEMORY erstellten Tabellen, da nur max_heap_table_size angewendet wird). Je nachdem, welcher Wert kleiner ist, wird zwischen den beiden angewendet.

tmp_table_size

Die größte Größe für temporäre Tabellen im Arbeitsspeicher (nicht MEMORY-Tabellen), obwohl, wenn max_heap_table_size kleiner ist, die untere Grenze gilt. Wenn eine temporäre Tabelle im Arbeitsspeicher das Limit überschreitet, konvertiert MySQL sie automatisch in eine temporäre Tabelle auf der Festplatte. Erhöhen Sie den Wert von tmp_table_size (und ggf. max_heap_table_size), wenn Sie viele erweiterte GROUP BY-Abfragen ausführen und viel Speicherplatz zur Verfügung haben. Sie können die Anzahl der erstellten internen temporären Tabellen auf der Festplatte mit der Gesamtzahl der erstellten internen temporären Tabellen vergleichen, indem Sie die Werte der Variablen Created_tmp_disk_tables und Created_tmp_tables vergleichen. In ClusterControl können Sie dies über Dashboard -> Grafik der temporären Objekte überwachen.

table_open_cache

Sie können den Wert dieser Variablen erhöhen, wenn Sie in Ihrem Datensatz eine große Anzahl von Tabellen haben, auf die häufig zugegriffen wird. Es wird für alle Threads angewendet, dh pro Verbindungsbasis. Der Wert gibt die maximale Anzahl von Tabellen an, die der Server in einer beliebigen Tabellen-Cache-Instanz geöffnet halten kann. Obwohl die Erhöhung dieses Werts die Anzahl der Dateideskriptoren erhöht, die mysqld benötigt, könnten Sie genauso gut in Betracht ziehen, Ihren open_files_limit-Wert zu überprüfen oder zu prüfen, wie groß die in Ihrem *nix-Betriebssystem eingestellten SOFT- und HARD-Limits sind. Sie können dies überwachen, indem Sie die Statusvariable Opened_tables überprüfen, ob Sie den Tabellen-Cache vergrößern müssen. Wenn der Wert von Opened_tables groß ist und Sie FLUSH TABLES nicht oft verwenden (was nur das Schließen und erneute Öffnen aller Tabellen erzwingt), sollten Sie den Wert der Variablen table_open_cache erhöhen. Wenn Sie einen kleinen Wert für table_open_cache haben und häufig auf eine große Anzahl von Tabellen zugegriffen wird, kann dies die Leistung Ihres Servers beeinträchtigen. Wenn Sie viele Einträge in der MySQL-Prozessliste mit dem Status „Opening tables“ oder „Closing tables“ bemerken, dann ist es an der Zeit, den Wert dieser Variablen anzupassen, aber beachten Sie die zuvor erwähnte Einschränkung. In ClusterControl können Sie dies unter Dashboards -> Table Open Cache Status oder Dashboards -> Open Tables überprüfen. Weitere Informationen finden Sie hier.

table_open_cache_instances

Das Festlegen dieser Variablen würde helfen, die Skalierbarkeit und natürlich die Leistung zu verbessern, wodurch Konflikte zwischen Sitzungen verringert würden. Der hier festgelegte Wert begrenzt die Anzahl der Cacheinstanzen für offene Tabellen. Der Cache für offene Tabellen kann in mehrere kleinere Cache-Instanzen der Größe table_open_cache / table_open_cache_instances partitioniert werden. Eine Sitzung muss nur eine Instanz sperren, um darauf für DML-Anweisungen zuzugreifen. Dadurch wird der Cache-Zugriff auf Instanzen segmentiert, was eine höhere Leistung für Vorgänge ermöglicht, die den Cache verwenden, wenn viele Sitzungen auf Tabellen zugreifen. (DDL-Anweisungen erfordern immer noch eine Sperre für den gesamten Cache, aber solche Anweisungen sind viel seltener als DML-Anweisungen.) Ein Wert von 8 oder 16 wird für Systeme empfohlen, die routinemäßig 16 oder mehr Kerne verwenden.

table_definition_cache

Cache-Tabellendefinitionen, d. h. hier werden die CREATE TABLE zwischengespeichert, um das Öffnen von Tabellen und nur einen Eintrag pro Tabelle zu beschleunigen. Es wäre sinnvoll, den Wert zu erhöhen, wenn Sie eine große Anzahl von Tabellen haben. Der Tabellendefinitions-Cache benötigt weniger Speicherplatz und verwendet im Gegensatz zum normalen Tabellen-Cache keine Dateideskriptoren. Peter Zaitsev von Percona schlägt vor, ob Sie die Einstellung der folgenden Formel ausprobieren können,

The number of user-defined tables + 10% unless 50K+ tables

Beachten Sie jedoch, dass der Standardwert auf der folgenden Formel basiert und auf ein Limit von 2000 begrenzt ist.

MIN(400 + table_open_cache / 2, 2000)

Falls Sie also eine größere Anzahl von Tabellen im Vergleich zum Standard haben, ist es sinnvoll, den Wert zu erhöhen. Berücksichtigen Sie, dass diese Variable bei InnoDB als weiches Limit für die Anzahl offener Tabelleninstanzen für den Datenwörterbuch-Cache verwendet wird. Es wendet den LRU-Mechanismus an, sobald es den aktuellen Wert dieser Variablen überschreitet. Das Limit hilft bei der Bewältigung von Situationen, in denen erhebliche Mengen an Arbeitsspeicher verwendet würden, um selten verwendete Tabelleninstanzen bis zum nächsten Serverneustart zwischenzuspeichern. Daher werden übergeordnete und untergeordnete Tabelleninstanzen mit Fremdschlüsselbeziehungen nicht in die LRU-Liste aufgenommen und könnten eine höhere als die durch table_definition_cache definierte Grenze auferlegen und werden während der LRU nicht aus dem Speicher entfernt. Darüber hinaus definiert der table_definition_cache ein weiches Limit für die Anzahl der InnoDB-Datei-pro-Tabelle-Tablespaces, die gleichzeitig geöffnet sein können, was auch von innodb_open_files gesteuert wird, und tatsächlich wird die höchste Einstellung zwischen diesen Variablen verwendet, wenn beide gesetzt sind . Wenn keine Variable festgelegt ist, wird table_definition_cache verwendet, das einen höheren Standardwert hat. Wenn die Anzahl offener Tablespace-Dateihandles die durch table_definition_cache oder innodb_open_files definierte Grenze überschreitet, durchsucht der LRU-Mechanismus die LRU-Liste der Tablespace-Datei nach Dateien, die vollständig geleert sind und derzeit nicht erweitert werden. Dieser Vorgang wird jedes Mal durchgeführt, wenn ein neuer Tablespace geöffnet wird. Wenn es keine „inaktiven“ Tablespaces gibt, werden keine Tablespace-Dateien geschlossen. Denken Sie also daran.

max_allowed_packet

Dies ist die maximale Größe pro Verbindung einer zurückgegebenen SQL-Abfrage oder -Zeile. Der Wert wurde zuletzt in MySQL 5.6 erhöht. In MySQL 8.0 (mindestens auf 8.0.3) beträgt der aktuelle Standardwert jedoch 64 MiB. Sie können dies anpassen, wenn Sie große BLOB-Zeilen haben, die herausgezogen (oder gelesen) werden müssen, andernfalls können Sie diese Standardeinstellungen bei 8.0 belassen, aber in älteren Versionen ist die Standardeinstellung 4 MiB, sodass Sie sich gegebenenfalls darum kümmern sollten auf den Fehler ER_NET_PACKET_TOO_LARGE stoßen. Das größtmögliche Paket, das zu oder von einem MySQL 8.0-Server oder -Client übertragen werden kann, ist 1 GB groß.

skip_name_resolve Der MySQL-Server verarbeitet eingehende Verbindungen nach Hostnamenauflösung. Standardmäßig deaktiviert MySQL keine Hostnamenauflösung, was bedeutet, dass es eine DNS-Suche durchführt, und zufällig, wenn DNS langsam ist, könnte dies die Ursache für eine schreckliche Leistung Ihrer Datenbank sein. Erwägen Sie, dies zu aktivieren, wenn Sie keine DNS-Auflösung benötigen, und profitieren Sie von der Verbesserung Ihrer MySQL-Leistung, wenn diese DNS-Suche deaktiviert ist. Beachten Sie, dass diese Variable nicht dynamisch ist, daher ist ein Neustart des Servers erforderlich, wenn Sie dies in Ihrer MySQL-Konfigurationsdatei festlegen. Optional können Sie den mysqld-Daemon starten, indem Sie die Option --skip-name-resolve übergeben, um dies zu aktivieren.

max_connections

Dies ist die Anzahl der zulässigen Verbindungen für Ihren MySQL-Server. Wenn Sie den Fehler in MySQL „Zu viele Verbindungen“ finden, sollten Sie ihn höher setzen. Standardmäßig reicht der Wert von 151 nicht aus, insbesondere bei einer Produktionsdatenbank und wenn man bedenkt, dass Sie über größere Ressourcen des Servers verfügen (verschwenden Sie Ihre Serverressourcen nicht, insbesondere wenn es sich um einen dedizierten MySQL-Server handelt). Sie müssen jedoch genügend Dateideskriptoren haben, sonst werden sie Ihnen ausgehen. Ziehen Sie in diesem Fall in Betracht, Ihr SOFT- und HARD-Limit Ihrer *nix-Betriebssysteme anzupassen und einen höheren Wert für open_files_limit in MySQL festzulegen (5000 ist das Standardlimit). Beachten Sie, dass es sehr häufig vorkommt, dass die Anwendung Verbindungen zur Datenbank nicht korrekt schließt, und das Festlegen eines hohen Werts für max_connections dazu führen kann, dass Ihr Server nicht mehr reagiert oder eine hohe Last auslastet. Die Verwendung eines Verbindungspools auf Anwendungsebene kann hier helfen, das Problem zu lösen.

thread_cache_size

Dies ist der Cache, um eine übermäßige Thread-Erzeugung zu verhindern. Wenn ein Client die Verbindung trennt, werden die Threads des Clients in den Cache gestellt, wenn dort weniger als thread_cache_size-Threads vorhanden sind. Anforderungen für Threads werden nach Möglichkeit durch Wiederverwendung von Threads aus dem Cache erfüllt, und nur wenn der Cache leer ist, wird ein neuer Thread erstellt. Diese Variable kann erhöht werden, um die Leistung zu verbessern, wenn Sie viele neue Verbindungen haben. Normalerweise bietet dies keine nennenswerte Leistungsverbesserung, wenn Sie über eine gute Thread-Implementierung verfügen. Wenn Ihr Server jedoch Hunderte von Verbindungen pro Sekunde sieht, sollten Sie thread_cache_size normalerweise hoch genug setzen, damit die meisten neuen Verbindungen zwischengespeicherte Threads verwenden. Indem Sie den Unterschied zwischen den Statusvariablen Connections und Threads_created untersuchen, können Sie sehen, wie effizient der Thread-Cache ist. Unter Verwendung der in der Dokumentation angegebenen Formel ist 8 + (max_connections / 100) gut genug.

query_cache_size

Für einige Setups ist diese Variable ihr schlimmster Feind. Bei einigen Systemen, die eine hohe Auslastung erfahren und mit vielen Lesevorgängen beschäftigt sind, wird Sie diese Variable verlangsamen. Es gab Benchmarks, die gut und getestet waren, z. B. von Percona. Diese Variable muss zusammen mit query_cache_type =0 ebenfalls auf 0 gesetzt werden, um sie zu deaktivieren. Die gute Nachricht in MySQL 8.0 ist, dass das MySQL-Team dies nicht mehr unterstützt, da diese Variable wirklich Leistungsprobleme verursachen kann. Ich muss ihrem Blog zustimmen, dass es unwahrscheinlich ist, dass die Vorhersagbarkeit der Leistung verbessert wird. Wenn Sie Abfrage-Caching verwenden möchten, empfehle ich die Verwendung von Redis oder ProxySQL.

Speicher-Engine – InnoDB

InnoDB ist eine ACID-konforme Speicher-Engine mit verschiedenen Funktionen, die zusammen mit Fremdschlüsselunterstützung (Declarative Referential Integrity) angeboten werden. Dies hat hier eine Menge Dinge zu sagen, aber bestimmte Variablen, die beim Tuning berücksichtigt werden müssen:

innodb_buffer_pool_size

Diese Variable verhält sich wie ein Schlüsselpuffer von MyISAM, hat aber viele Dinge zu bieten. Da InnoDB stark auf den Pufferpool angewiesen ist, sollten Sie diesen Wert normalerweise auf 70 % bis 80 % des Arbeitsspeichers Ihres Servers setzen. Günstig ist auch, dass Sie einen größeren Speicherplatz als Ihren Datensatz haben und einen höheren Wert für Ihren Pufferpool festlegen, aber nicht zu viel. In ClusterControl kann dies mithilfe unseres Diagramms Dashboards -> InnoDB Metrics -> InnoDB Buffer Pool Pages überwacht werden. Sie können dies auch mit SHOW GLOBAL STATUS überwachen, indem Sie die Variablen Innodb_buffer_pool_pages*.

verwenden

innodb_buffer_pool_instances

Für Ihre Parallelitäts-Workload kann das Festlegen dieser Variablen die Parallelität verbessern und Konflikte reduzieren, da verschiedene Lese-/Schreib-Threads auf zwischengespeicherte Seiten zugreifen. Minimum innodb_buffer_pool_instances sollte zwischen 1 (Minimum) und 64 (Maximum) liegen. Jede Seite, die im Pufferpool gespeichert oder daraus gelesen wird, wird unter Verwendung einer Hash-Funktion zufällig einer der Pufferpoolinstanzen zugewiesen. Jeder Pufferpool verwaltet seine eigenen freien Listen, Flush-Listen, LRUs und alle anderen mit einem Pufferpool verbundenen Datenstrukturen und wird durch seinen eigenen Pufferpool-Mutex geschützt. Beachten Sie, dass diese Option nur wirksam wird, wenn innodb_buffer_pool_size>=1GiB ist und ihre Größe auf die Pufferpoolinstanzen aufgeteilt wird.

innodb_log_file_size

Diese Variable ist die Protokolldatei in einer Protokollgruppe. Die kombinierte Größe der Protokolldateien (innodb_log_file_size * innodb_log_files_in_group) darf einen Maximalwert von etwas weniger als 512 GB nicht überschreiten. Laut Vadim ist eine größere Protokolldatei besser für die Leistung, hat aber einen Nachteil (einen erheblichen), über den Sie sich Sorgen machen müssen:die Wiederherstellungszeit nach einem Absturz. Sie müssen die Wiederherstellungszeit im seltenen Fall einer Wiederherstellung nach einem Absturz gegen die Maximierung des Durchsatzes während des Spitzenbetriebs abwägen. Diese Einschränkung kann zu einem 20-mal längeren Wiederherstellungsprozess nach einem Absturz führen!

Genauer gesagt, ein größerer Wert wäre gut für InnoDB-Transaktionsprotokolle und entscheidend für eine gute und stabile Schreibleistung. Je größer der Wert, desto weniger Checkpoint-Flush-Aktivität ist im Pufferpool erforderlich, wodurch Festplatten-E/A eingespart wird. Der Wiederherstellungsprozess ist jedoch ziemlich langsam, sobald Ihre Datenbank abnormal heruntergefahren wurde (Absturz oder Beenden, entweder OOM oder versehentlich). Idealerweise können Sie 1-2 GiB in der Produktion haben, aber Sie können dies natürlich anpassen. Das Benchmarking dieser Änderungen kann ein großer Vorteil sein, um zu sehen, wie sie sich insbesondere nach einem Absturz verhalten.

innodb_log_buffer_size

Um Festplatten-I/O zu sparen, schreibt InnoDB die Änderungsdaten in den Protokollpuffer von lt und verwendet den Wert von innodb_log_buffer_size mit einem Standardwert von 8 MB. Dies ist besonders bei großen Transaktionen von Vorteil, da das Änderungsprotokoll vor dem Commit der Transaktion nicht auf die Festplatte geschrieben werden muss. Wenn Ihr Schreibverkehr zu hoch ist (Einfügungen, Löschungen, Aktualisierungen), spart eine Vergrößerung des Puffers Festplatten-I/O.

innodb_flush_log_at_trx_commit

Wenn innodb_flush_log_at_trx_commit auf 1 gesetzt ist, wird der Protokollpuffer bei jedem Transaktions-Commit in die Protokolldatei auf der Festplatte geleert und bietet maximale Datenintegrität, wirkt sich aber auch auf die Leistung aus. Das Festlegen auf 2 bedeutet, dass der Protokollpuffer bei jedem Transaktionscommit in den Dateicache des Betriebssystems geleert wird. Die Auswirkung von 2 ist optimal und verbessert die Leistung, wenn Sie Ihre ACID-Anforderungen lockern und es sich leisten können, im Falle eines Betriebssystemabsturzes Transaktionen für die letzten ein oder zwei Sekunden zu verlieren.

innodb_thread_concurrency

Mit Verbesserungen an der InnoDB-Engine wird empfohlen, der Engine zu erlauben, die Parallelität zu steuern, indem sie auf dem Standardwert (null) gehalten wird. Wenn Sie Parallelitätsprobleme sehen, können Sie diese Variable optimieren. Ein empfohlener Wert ist das Zweifache der Anzahl der CPUs plus der Anzahl der Festplatten. Seine dynamische Variable bedeutet, dass sie gesetzt werden kann, ohne den MySQL-Server neu zu starten.

innodb_flush_method

Diese Variable muss jedoch ausprobiert und getestet werden, welche Hardware am besten zu Ihnen passt. Wenn Sie ein RAID mit batteriegestütztem Cache verwenden, hilft DIRECT_IO, den E/A-Druck zu verringern. Direkte E/A wird nicht zwischengespeichert, sodass eine doppelte Pufferung mit Pufferpool und Dateisystem-Cache vermieden wird. Wenn Ihre Festplatte in SAN gespeichert ist, ist O_DSYNC möglicherweise schneller für eine leselastige Arbeitslast mit hauptsächlich SELECT-Anweisungen.

innodb_file_per_table

innodb_file_per_table ist ab MySQL 5.6 standardmäßig aktiviert. Dies wird normalerweise empfohlen, da es einen riesigen gemeinsam genutzten Tablespace vermeidet und es Ihnen ermöglicht, Speicherplatz zurückzugewinnen, wenn Sie eine Tabelle löschen oder abschneiden. Separater Tablespace profitiert auch für das partielle Xtrabackup-Backup-Schema.

innodb_stats_on_metadata

Dies versucht, den Prozentsatz der schmutzigen Seiten unter Kontrolle zu halten, und vor dem Innodb-Plug-in war dies wirklich die einzige Möglichkeit, das Leeren des schmutzigen Puffers zu optimieren. Ich habe jedoch Server mit 3% schmutzigen Puffern gesehen und sie erreichen ihr maximales Checkpoint-Alter. Die Art und Weise, wie dies das Leeren des schmutzigen Puffers erhöht, skaliert auch nicht gut auf Subsystemen mit hoher io, es verdoppelt effektiv nur das Leeren des schmutzigen Puffers pro Sekunde, wenn der Prozentsatz der schmutzigen Seiten diesen Wert überschreitet.

innodb_io_capacity

Trotz all unserer großen Hoffnungen, dass es Innodb ermöglichen würde, unsere IO in allen Operationen besser zu nutzen, steuert diese Einstellung einfach die Menge an Dirty Page Flushing pro Sekunde (und andere Hintergrundaufgaben wie Read-Ahead). Machen Sie diese größer, Sie spülen mehr pro Sekunde. Dies passt sich nicht an, es macht einfach jede Sekunde so viele IOps, wenn schmutzige Puffer zu leeren sind. Es wird jede Optimierung der IO-Konsolidierung effektiv eliminieren, wenn Sie eine ausreichend geringe Schreiblast haben (d. h. schmutzige Seiten werden fast sofort geleert, in diesem Fall sind wir ohne Transaktionsprotokoll möglicherweise besser dran). Es kann auch schnell Lese- und Schreibvorgänge von Daten in das Transaktionsprotokoll verhungern, wenn Sie dies zu hoch einstellen.

innodb_write_io_threads

Steuert, wie viele Threads Schreibvorgänge auf der Festplatte ausführen. Ich bin mir nicht sicher, warum dies immer noch nützlich ist, wenn Sie Linux-natives AIO verwenden können. Diese können auch durch Dateisysteme unbrauchbar gemacht werden, die kein paralleles Schreiben in dieselbe Datei durch mehr als einen Thread zulassen (insbesondere wenn Sie relativ wenige Tabellen haben und/oder die globalen Tablespaces verwenden)

innodb_adaptive_flushing

Gibt an, ob die Rate zum Leeren von fehlerhaften Seiten im InnoDB-Pufferpool basierend auf der Arbeitslast dynamisch angepasst werden soll. Das dynamische Anpassen der Spülrate soll Bursts von I/O-Aktivität vermeiden. Normalerweise ist dies standardmäßig aktiviert. Wenn diese Variable aktiviert ist, versucht sie, basierend auf der Anzahl der schmutzigen Seiten und der Wachstumsrate des Transaktionsprotokolls, intelligenter beim Leeren zu sein.

innodb_dedicated_server

Diese Variable ist neu in MySQL 8.0, das global angewendet wird und einen Neustart von MySQL erfordert, da es sich nicht um eine dynamische Variable handelt. Wie in der Dokumentation angegeben, soll diese Variable jedoch nur aktiviert werden, wenn Ihr MySQL auf einem dedizierten Server ausgeführt wird. Aktivieren Sie dies andernfalls nicht auf einem gemeinsam genutzten Host oder teilt Systemressourcen mit anderen Anwendungen. Wenn dies aktiviert ist, führt InnoDB eine automatische Konfiguration für die Speichermenge durch, die für die Variablen innodb_buffer_pool_size, innodb_log_file_size, innodb_flush_method erkannt wird. Der Nachteil ist nur, dass Sie nicht die Möglichkeit haben, Ihre gewünschten Werte auf die erwähnten erkannten Variablen anzuwenden.

MyISAM

key_buffer_size

InnoDB ist jetzt die Standardspeicher-Engine von MySQL, der Standardwert für key_buffer_size kann wahrscheinlich verringert werden, es sei denn, Sie verwenden MyISAM produktiv als Teil Ihrer Anwendung (aber wer verwendet MyISAM jetzt in der Produktion?). Ich würde hier vorschlagen, vielleicht 1 % des RAM oder 256 MiB zu Beginn einzustellen, wenn Sie über mehr Speicher verfügen, und den verbleibenden Speicher für Ihren Betriebssystem-Cache und InnoDB-Pufferpool zu reservieren.

Sonstige Leistungsbestimmungen

slow_query_log

Natürlich trägt diese Variable nicht dazu bei, Ihren MySQL-Server zu verbessern. Diese Variable kann Ihnen jedoch bei der Analyse langsamer Abfragen helfen. Der Wert kann auf 0 oder AUS gesetzt werden, um die Protokollierung zu deaktivieren. Setzen Sie ihn auf 1 oder ON, um dies zu aktivieren. Der Standardwert hängt davon ab, ob die Option --slow_query_log angegeben ist. Das Ziel für die Protokollausgabe wird durch die Systemvariable log_output gesteuert; Wenn dieser Wert NONE ist, werden keine Protokolleinträge geschrieben, selbst wenn das Protokoll aktiviert ist. Sie können den Dateinamen oder das Ziel der Abfrageprotokolldatei festlegen, indem Sie die Variable slow_query_log_file.

festlegen

long_query_time

Wenn eine Abfrage länger als diese Anzahl von Sekunden dauert, erhöht der Server die Statusvariable Slow_queries. Wenn das Protokoll für langsame Abfragen aktiviert ist, wird die Abfrage in der Protokolldatei für langsame Abfragen protokolliert. Dieser Wert wird in Echtzeit gemessen, nicht in CPU-Zeit, sodass eine Abfrage, die auf einem leicht belasteten System unter dem Schwellenwert liegt, auf einem stark belasteten System möglicherweise über dem Schwellenwert liegt. Die Mindest- und Standardwerte von long_query_time sind 0 bzw. 10. Beachten Sie auch, dass, wenn die Variable min_examined_row_limit auf> 0 gesetzt ist, keine Abfragen protokolliert werden, selbst wenn es zu lange dauert, wenn die Anzahl der zurückgegebenen Zeilen kleiner als der in min_examined_row_limit festgelegte Wert ist.

Weitere Informationen zum Optimieren Ihrer langsamen Abfrageprotokollierung finden Sie in der Dokumentation hier.

sync_binlog

Diese Variable steuert, wie oft MySQL Binlogs mit der Festplatte synchronisiert. Standardmäßig (>=5.7.7) ist dies auf 1 eingestellt, was bedeutet, dass es mit der Festplatte synchronisiert wird, bevor Transaktionen festgeschrieben werden. Dies wirkt sich jedoch aufgrund der erhöhten Anzahl von Schreibvorgängen negativ auf die Leistung aus. Dies ist jedoch die sicherste Einstellung, wenn Sie zusammen mit Ihren Sklaven streng ACID-konform sein möchten. Alternativ können Sie dies auf 0 setzen, wenn Sie die Festplattensynchronisierung deaktivieren und sich einfach darauf verlassen möchten, dass das Betriebssystem das Binärprotokoll von Zeit zu Zeit auf die Festplatte schreibt. Wenn Sie ihn höher als 1 setzen, bedeutet dies, dass das Binlog mit der Festplatte synchronisiert wird, nachdem N Binärlog-Commit-Gruppen gesammelt wurden, wobei N> 1 ist.

Pufferpool löschen/wiederherstellen

Es ist ziemlich üblich, dass Ihre Produktionsdatenbank nach einem Kaltstart/Neustart aufgewärmt werden muss. Durch das Sichern des aktuellen Pufferpools vor einem Neustart wird der Inhalt aus dem Pufferpool gespeichert, und sobald er hochgefahren ist, wird der Inhalt wieder in den Pufferpool geladen. Dadurch wird die Notwendigkeit vermieden, Ihre Datenbank wieder aufzuwärmen der Cache. Beachten Sie, dass diese Version seitdem in 5.6 eingeführt wurde, aber Percona Server 5.5 hat sie bereits verfügbar, nur für den Fall, dass Sie sich fragen. Um diese Funktion zu aktivieren, setzen Sie beide Variablen innodb_buffer_pool_dump_at_shutdown =ON und innodb_buffer_pool_load_at_startup =ON.

Hardware

Wir haben jetzt 2019, es gab viele neue Hardware-Verbesserungen. Normalerweise gibt es keine zwingende Voraussetzung dafür, dass MySQL eine bestimmte Hardware benötigt, aber dies hängt davon ab, was Sie von der Datenbank erwarten. Ich würde erwarten, dass Sie diesen Blog nicht lesen, weil Sie einen Test machen, ob er auf einem Intel Pentium 200 MHz läuft.

Für die CPU sind schnellere Prozessoren mit mehreren Kernen für MySQL in den neuesten Versionen mindestens seit 5.6 optimal. Die Xeon/Itanium-Prozessoren von Intel können teuer sein, wurden aber für skalierbare und zuverlässige Computerplattformen getestet. Amazon hat seine EC2-Instances ausgeliefert, die auf einer ARM-Architektur ausgeführt werden. Obwohl ich persönlich nicht versucht habe, MySQL auf einer ARM-Architektur auszuführen, oder mich an die Ausführung erinnere, gibt es Benchmarks, die vor Jahren erstellt wurden. Moderne CPUs können ihre Frequenzen basierend auf Temperatur, Last und Energiesparrichtlinien des Betriebssystems nach oben und unten skalieren. Es besteht jedoch die Möglichkeit, dass Ihre CPU-Einstellungen in Ihrem Linux-Betriebssystem auf einen anderen Gouverneur eingestellt sind. Sie können das überprüfen oder mit dem „Leistungsregler“ einstellen, indem Sie Folgendes tun:

echo performance | sudo tee /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor

Für Speicher ist es sehr wichtig, dass Ihr Speicher groß ist und der Größe Ihres Datensatzes entsprechen kann. Stellen Sie sicher, dass Sie swappiness =1 haben. Sie können es überprüfen, indem Sie sysctl überprüfen oder die Datei in procfs überprüfen. Dies wird wie folgt erreicht:

$ sysctl -e vm.swappiness
vm.swappiness = 1

Oder wie folgt auf den Wert 1 setzen

$ sudo sysctl vm.swappiness=1
vm.swappiness = 1

Eine weitere großartige Sache, die Sie für Ihre Speicherverwaltung in Betracht ziehen sollten, ist das Deaktivieren von THP (Transparrent Huge Pages). Ich erinnere mich, dass wir in der Vergangenheit einige seltsame Probleme mit der CPU-Auslastung hatten und dachten, es liege an Festplatten-E/A. Es stellte sich heraus, dass das Problem im Kernel-Khugepaged-Thread lag, der während der Laufzeit Speicher dynamisch zuweist. Nicht nur das, während der Kernel zur Defragmentierung geht, wird Ihr Speicher schnell zugewiesen, wenn er ihn an THP weitergibt. Standard-HugePages-Speicher wird beim Start vorab zugewiesen und ändert sich während der Laufzeit nicht. Sie können dies wie folgt überprüfen und deaktivieren:

$ cat /sys/kernel/mm/transparent_hugepage/enabled
$ echo "never" > /sys/kernel/mm/transparent_hugepage/enabled

Für Disk ist es wichtig, dass Sie einen guten Durchsatz haben. Die Verwendung von RAID10 ist die beste Einrichtung für eine Datenbank mit einer Batteriesicherungseinheit. Mit dem Aufkommen von Flash-Laufwerken, die einen hohen Festplattendurchsatz und eine hohe Festplatten-E/A für Lese-/Schreibvorgänge bieten, ist es wichtig, dass sie die hohe Festplattenauslastung und Festplatten-E/A bewältigen können.

Betriebssystem

Die meisten Produktionssysteme, die auf MySQL laufen, laufen auf Linux. Das liegt daran, dass MySQL unter Linux getestet und einem Benchmarking unterzogen wurde, und es klingt, als wäre es der De-facto-Standard für eine MySQL-Installation. Natürlich hindert Sie nichts daran, es auf einer Unix- oder Windows-Plattform zu verwenden. Es wäre einfacher, wenn Ihre Plattform getestet wurde und es eine große Community gibt, die Ihnen helfen kann, falls Sie auf Probleme stoßen. Die meisten Setups laufen auf RHEL/Centos/Fedora- und Debian/Ubuntu-Systemen. In AWS hat Amazon sein Amazon Linux, das meines Erachtens auch von einigen in der Produktion verwendet wird.

Am wichtigsten, was Sie bei Ihrer Einrichtung berücksichtigen sollten, ist, dass Ihr Dateisystem entweder XFS oder Ext4 verwendet. Sicherlich gibt es Vor- und Nachteile zwischen diesen beiden Dateisystemen, aber ich werde hier nicht auf die Details eingehen. Einige sagen, dass XFS Ext4 übertrifft, aber es gibt auch Berichte, dass Ext4 XFS übertrifft. ZFS ist auch ein guter Kandidat für ein alternatives Dateisystem. Jervin Real (von Percona) hat eine großartige Ressource zu diesem Thema, Sie können diese Präsentation während der ZFS-Konferenz überprüfen.

Externe Links

https://developer.okta.com/blog/2015/05/22/tcmalloc

https://www.percona.com/blog/2012/07/05/impact-of-memory-allocators-on-mysql-performance/

https://www.percona.com/live/18/sessions/benchmark-noise-reduction-how-to-configure-your-machines-for-stable-results

https://zfs.datto.com/2018_slides/real.pdf

https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/disabling-transparent-hugepages.html#GUID-02E9147D-D565-4AF8-B12A-8E6E9F74BEEA