So messen Sie die Leistung von MySQL-Abfragen mit mysqlslap

Einführung

MySQL wird mit einem praktischen kleinen Diagnosetool namens * mysqlslap * ausgeliefert, das es seit Version 5.1.4 gibt. Es ist ein Benchmarking-Tool, mit dem Datenbankadministratoren und Entwickler ihre Datenbankserver testen können.

mysqlslap kann eine große Anzahl von Clientverbindungen emulieren, die gleichzeitig auf den Datenbankserver treffen. Die Lasttestparameter sind vollständig konfigurierbar und die Ergebnisse verschiedener Testläufe können zur Feinabstimmung des Datenbankdesigns oder der Hardwareressourcen verwendet werden.

In diesem Tutorial erfahren Sie, wie Sie mithilfe von mysqlslap eine MySQL-Datenbank mit einigen grundlegenden Abfragen laden und wie uns das Benchmarking dabei helfen kann, diese Abfragen zu optimieren. Nach einigen grundlegenden Demonstrationen werden wir ein ziemlich realistisches Testszenario durchlaufen, in dem wir eine Kopie einer vorhandenen Datenbank zum Testen erstellen, Abfragen aus einem Protokoll abrufen und den Test über ein Skript ausführen.

Die in diesem Tutorial gezeigten Befehle, Pakete und Dateien wurden unter * CentOS 7 * getestet. Die Konzepte bleiben für andere Distributionen gleich.

Welche Servergröße soll ich verwenden?

Wenn Sie ein Benchmarking für einen bestimmten Datenbankserver durchführen möchten, sollten Sie auf einem Server mit denselben Spezifikationen und mit einer genauen Kopie Ihrer installierten Datenbank testen.

Wenn Sie dieses Lernprogramm zu Lernzwecken durcharbeiten und jeden darin enthaltenen Befehl ausführen möchten, empfehlen wir mindestens ein * 2 GB * Droplet. Da die Befehle in diesem Lernprogramm den Server belasten sollen, tritt möglicherweise eine Zeitüberschreitung auf einem kleineren Server auf.

Die Beispielausgabe in diesem Lernprogramm wurde auf verschiedene Arten erstellt, um die Beispiele für den Unterricht zu optimieren.

Erster Schritt - Installieren von MySQL Community Server auf einem Testsystem

Zunächst installieren wir eine neue Kopie von MySQL Community Server in einer Testdatenbank. * Sie sollten keine Befehle oder Abfragen aus diesem Lernprogramm auf einem Produktionsdatenbankserver ausführen. *

Diese Tests belasten den Testserver und können zu Verzögerungen oder Ausfallzeiten auf einem Produktionsserver führen. Dieses Tutorial wurde mit der folgenden Umgebung getestet:

Zunächst erstellen wir ein Verzeichnis, in dem alle zu diesem Lernprogramm gehörenden Dateien gespeichert werden. Dies wird dazu beitragen, die Dinge in Ordnung zu halten. Navigieren Sie in dieses Verzeichnis:

sudo mkdir /mysqlslap_tutorial
cd /mysqlslap_tutorial

Als nächstes werden wir das MySQL Community Release yum Repository herunterladen. Das Repository, das wir herunterladen, ist für Red Hat Enterprise Linux 7, das für CentOS 7 funktioniert:

sudo wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm

Als nächstes können wir den Befehl + rpm -Uvh + ausführen, um das Repository zu installieren:

sudo rpm -Uvh mysql-community-release-el7-5.noarch.rpm

Überprüfen Sie, ob die Repositorys installiert wurden, indem Sie den Inhalt des Ordners + / etc / yum.repos.d + überprüfen:

sudo ls -l /etc/yum.repos.d

Die Ausgabe sollte folgendermaßen aussehen:

-rw-r--r--. 1 root root 1612 Jul  4 21:00 CentOS-Base.repo
-rw-r--r--. 1 root root  640 Jul  4 21:00 CentOS-Debuginfo.repo
-rw-r--r--. 1 root root 1331 Jul  4 21:00 CentOS-Sources.repo
-rw-r--r--. 1 root root  156 Jul  4 21:00 CentOS-Vault.repo
-rw-r--r--. 1 root root 1209 Jan 29  2014 mysql-community.repo
-rw-r--r--. 1 root root 1060 Jan 29  2014 mysql-community-source.repo

Wir können auch überprüfen, ob das richtige MySQL-Release für die Installation aktiviert ist:

sudo yum repolist enabled | grep mysql

In unserem Fall * MySQL 5.6 Community Server * ist das, was wir wollten:

mysql-connectors-community/x86_64       MySQL Connectors Community           10
mysql-tools-community/x86_64            MySQL Tools Community                 6
mysql56-community/x86_64                MySQL 5.6 Community Server           64

Installieren Sie den MySQL Community Server:

sudo yum install mysql-community-server

Überprüfen Sie nach Abschluss des Vorgangs die installierten Komponenten:

sudo yum list installed | grep mysql

Die Liste sollte folgendermaßen aussehen:

mysql-community-client.x86_64      5.6.20-4.el7      @mysql56-community
mysql-community-common.x86_64      5.6.20-4.el7      @mysql56-community
mysql-community-libs.x86_64        5.6.20-4.el7      @mysql56-community
mysql-community-release.noarch     el7-5             installed
mysql-community-server.x86_64      5.6.20-4.el7      @mysql56-community

Als nächstes müssen wir sicherstellen, dass der MySQL-Daemon läuft und automatisch startet, wenn der Server bootet. Überprüfen Sie den Status des mysqld-Daemons.

sudo systemctl status mysqld.service

Wenn es gestoppt ist, wird folgende Ausgabe angezeigt:

mysqld.service - MySQL Community Server
  Loaded: loaded (/usr/lib/systemd/system/mysqld.service; disabled)
  Active: inactive (dead)

Starten Sie den Dienst:

sudo systemctl start mysqld.service

Stellen Sie sicher, dass es so konfiguriert ist, dass es beim Booten automatisch gestartet wird:

sudo systemctl enable mysqld.service

Schließlich müssen wir MySQL sichern:

sudo mysql_secure_installation

Daraufhin wird eine Reihe von Eingabeaufforderungen angezeigt. Nachfolgend werden die Eingabeaufforderungen mit den Antworten angezeigt, die Sie eingeben sollten. Am Anfang gibt es kein Passwort für den MySQL-Root-Benutzer. Drücken Sie einfach die Eingabetaste.

Bei den Eingabeaufforderungen müssen Sie ein neues sicheres Root-Passwort eingeben, das Sie selbst auswählen sollten. Sie sollten mit * y * antworten, um das anonyme Datenbankbenutzerkonto zu entfernen, die Remote-Root-Anmeldung zu deaktivieren, die Berechtigungstabellen neu zu laden usw.

...
Enter current password for root (enter for none):
OK, successfully used password, moving on...
...
Set root password? [Y/n]
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
...
Remove anonymous users? [Y/n]
... Success!
...
Disallow root login remotely? [Y/n]
... Success!
Remove test database and access to it? [Y/n]
- Dropping test database...
... Success!
...
Reload privilege tables now? [Y/n]
... Success!
Cleaning up...

Jetzt können wir eine Verbindung zur Datenbank herstellen und sicherstellen, dass alles funktioniert:

sudo mysql -h localhost -u root -p

Geben Sie das Root-MySQL-Passwort ein, das Sie gerade an der Eingabeaufforderung festgelegt haben. Die Ausgabe sollte folgendermaßen aussehen:

Enter password:
Welcome to the MySQL monitor....

mysql>

Geben Sie an der Eingabeaufforderung den Befehl ein, um alle Ihre Datenbanken anzuzeigen:

show databases;

Die Ausgabe sollte folgendermaßen aussehen:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

Zuletzt erstellen wir ein Benutzerkonto mit dem Namen. Dieses Konto wird verwendet, um sich bei MySQL anstelle des Root-Benutzers anzumelden. Stellen Sie sicher, dass Sie für diesen Benutzer Ihr eigenes Passwort eingeben. Wir gewähren diesem Konto auch alle Berechtigungen. Geben Sie an der MySQL-Eingabeaufforderung die folgenden Befehle ein:

create user sysadmin identified by '';

Ausgabe:

Query OK, 0 rows affected (0.00 sec)

Gewähren Sie die Privilegien:

grant all on *.* to sysadmin;

Ausgabe:

Query OK, 0 rows affected (0.01 sec)

Kehren wir zunächst zur Eingabeaufforderung des Betriebssystems zurück:

quit;

Ausgabe:

Bye

Schritt Zwei - Installieren einer Beispieldatenbank

Als nächstes müssen wir eine Beispieldatenbank zum Testen installieren. Diese Datenbank heißt * employee * und ist unter http://dev.mysql.com/doc/index-other.html über die MySQL-Website frei zugänglich.] Die Datenbank kann auch von Launchpad heruntergeladen werden. Die Mitarbeiterdatenbank wurde von Patrick Crews und Giuseppe Maxia entwickelt. Die Originaldaten wurden von Fusheng Wang und Carlo Zaniolo von Siemens Corporate Research erstellt.

Wir wählen die Mitarbeiterdatenbank, weil sie einen großen Datensatz enthält. Die Datenbankstruktur ist recht einfach: Sie enthält nur sechs Tabellen. Die darin enthaltenen Daten enthalten jedoch mehr als 3.000.000 Mitarbeiterdatensätze (die Gehaltstabelle selbst enthält fast drei Millionen Zeilen). Auf diese Weise können wir eine realistischere Produktionsauslastung erzielen.

Stellen wir zunächst sicher, dass wir uns im Verzeichnis befinden:

cd /mysqlslap_tutorial

Laden Sie die neueste Version der Mitarbeiter-Beispieldatenbank herunter:

sudo wget https://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2

Installieren Sie das bzip2-Tool, damit wir das Archiv entpacken können:

sudo yum install bzip2

Entpacken Sie das Datenbankarchiv. Dies wird eine Minute dauern. Wir machen das in zwei Schritten:

sudo bzip2 -dfv employees_db-full-1.0.6.tar.bz2
sudo tar -xf employees_db-full-1.0.6.tar

Der Inhalt wird in ein separates, neues Verzeichnis namens dekomprimiert. Wir müssen in dieses Verzeichnis navigieren, um die Abfrage auszuführen, mit der die Datenbank installiert wird. Der Inhalt umfasst ein README-Dokument, ein Änderungsprotokoll, Datensicherungen und verschiedene SQL-Abfragedateien, mit denen die Datenbankstrukturen erstellt werden:

cd employees_db
ls -l

Folgendes sollten Sie sehen:

-rw-r--r--. 1 501 games       752 Mar 30  2009 Changelog
-rw-r--r--. 1 501 games      6460 Oct  9  2008 employees_partitioned2.sql
-rw-r--r--. 1 501 games      7624 Feb  6  2009 employees_partitioned3.sql
-rw-r--r--. 1 501 games      5660 Feb  6  2009 employees_partitioned.sql
-rw-r--r--. 1 501 games      3861 Nov 28  2008 employees.sql
-rw-r--r--. 1 501 games       241 Jul 30  2008 load_departments.dump
-rw-r--r--. 1 501 games  13828291 Mar 30  2009 load_dept_emp.dump
-rw-r--r--. 1 501 games      1043 Jul 30  2008 load_dept_manager.dump
-rw-r--r--. 1 501 games  17422825 Jul 30  2008 load_employees.dump
-rw-r--r--. 1 501 games 115848997 Jul 30  2008 load_salaries.dump
-rw-r--r--. 1 501 games  21265449 Jul 30  2008 load_titles.dump
-rw-r--r--. 1 501 games      3889 Mar 30  2009 objects.sql
-rw-r--r--. 1 501 games      2211 Jul 30  2008 README
-rw-r--r--. 1 501 games      4455 Mar 30  2009 test_employees_md5.sql
-rw-r--r--. 1 501 games      4450 Mar 30  2009 test_employees_sha.sql

Führen Sie diesen Befehl aus, um eine Verbindung zu MySQL herzustellen, und führen Sie das Skript aus, mit dem die Datenbank erstellt und die Daten geladen werden:

sudo mysql -h localhost -u sysadmin -p -t < employees.sql

Geben Sie an der Eingabeaufforderung das Kennwort ein, das Sie im vorherigen Abschnitt für den MySQL-Benutzer * sysadmin * erstellt haben.

Die Prozessausgabe sieht folgendermaßen aus. Die Ausführung dauert ungefähr eine Minute:

+-----------------------------+
| INFO                        |
+-----------------------------+
| CREATING DATABASE STRUCTURE |
+-----------------------------+
+------------------------+
| INFO                   |
+------------------------+
| storage engine: InnoDB |
+------------------------+
+---------------------+
| INFO                |
+---------------------+
| LOADING departments |
+---------------------+
+-------------------+
| INFO              |
+-------------------+
| LOADING employees |
+-------------------+
+------------------+
| INFO             |
+------------------+
| LOADING dept_emp |
+------------------+
+----------------------+
| INFO                 |
+----------------------+
| LOADING dept_manager |
+----------------------+
+----------------+
| INFO           |
+----------------+
| LOADING titles |
+----------------+
+------------------+
| INFO             |
+------------------+
| LOADING salaries |
+------------------+

Jetzt können Sie sich bei MySQL anmelden und einige grundlegende Abfragen ausführen, um zu überprüfen, ob die Daten erfolgreich importiert wurden.

sudo mysql -h localhost -u sysadmin -p

Geben Sie das Passwort für den * sysadmin * MySQL-Benutzer ein.

Überprüfen Sie die Liste der Datenbanken für die neue Datenbank:

show databases;

Ausgabe:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.01 sec)

Verwenden Sie die Mitarbeiterdatenbank:

use employees;

Überprüfen Sie die Tabellen darin:

show tables;

Ausgabe:

+---------------------+
| Tables_in_employees |
+---------------------+
| departments         |
| dept_emp            |
| dept_manager        |
| employees           |
| salaries            |
| titles              |
+---------------------+
6 rows in set (0.01 sec)

Wenn Sie möchten, können Sie die Details für jede dieser Tabellen überprüfen. Wir überprüfen nur die Informationen für die Tabelle:

describe titles;

Ausgabe:

+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| emp_no    | int(11)     | NO   | PRI | NULL    |       |
| title     | varchar(50) | NO   | PRI | NULL    |       |
| from_date | date        | NO   | PRI | NULL    |       |
| to_date   | date        | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

Überprüfen Sie die Anzahl der Einträge:

mysql> select count(*) from titles;
+----------+
| count(*) |
+----------+
|   443308 |
+----------+
1 row in set (0.14 sec)

Überprüfen Sie die anderen gewünschten Daten. Wir können jetzt zur Eingabeaufforderung unseres Betriebssystems zurückkehren:

quit;

Schritt Drei - Verwenden von mysqlslap

Jetzt können wir mysqlslap verwenden. mysqlslap kann über eine reguläre Shell-Eingabeaufforderung aufgerufen werden, sodass Sie sich nicht explizit bei MySQL anmelden müssen. In diesem Tutorial öffnen wir jedoch eine weitere Terminalverbindung zu unserem Linux-Server und starten von dort aus eine neue MySQL-Sitzung mit dem zuvor erstellten * sysadmin * -Benutzer, damit wir einige Dinge in MySQL einfacher überprüfen und aktualisieren können. Wir haben also eine Eingabeaufforderung für unseren sudo-Benutzer und eine bei MySQL angemeldete Eingabeaufforderung.

Bevor wir zu Testzwecken auf bestimmte Befehle eingehen, sollten Sie sich diese Liste der nützlichsten mysqlslap-Optionen ansehen. Auf diese Weise können Sie später Ihre eigenen mysqlslap-Befehle entwerfen.

Option What it means

–user

MySQL username to connect to the database server

–password

Password for the user account. It’s best to leave it blank in command line

–host

MySQL database server name

–port

Port number for connecting to MySQL if the default is not used

–concurrency

The number of simultaneous client connections mysqlslap will emulate

–iterations

The number of times the test query will be run

–create-schema

The schema in which to run the tests

–query

The query to execute. This can either be a SQL query string or a path to a SQL script file

–create

The query to create a table. Again, this can be a query string or a path to a SQL file

–delimiter

The delimiter used to separate multiple SQL statements

–engine

The MySQL database engine to use (e.g., InnoDB)

–auto-generate-sql

Lets MySQL perform load testing with its own auto-generated SQL command

Anwendungsfall: Benchmarking mit automatisch generiertem SQL und Daten

Wir beginnen mit der automatischen SQL-Generierung von mysqlslap. Wenn wir automatisch generiertes SQL verwenden, erstellt mysqlslap eine separate temporäre Datenbank - passend mysqlslap genannt. Diese Datenbank enthält eine einfache Tabelle mit einer Ganzzahl- und einer Varchar-Typ-Spalte, die mit Beispieldaten gefüllt sind. Auf diese Weise können Sie schnell und einfach die Gesamtleistung des Datenbankservers überprüfen.

Zunächst testen wir eine einzelne Client-Verbindung, indem wir eine Iteration eines automatisch generierten SQL durchführen:

sudo mysqlslap --user=sysadmin --password --host=localhost  --auto-generate-sql --verbose

Die Ausgabe sollte folgendermaßen aussehen:

Benchmark
       Average number of seconds to run all queries: 0.009 seconds
       Minimum number of seconds to run all queries: 0.009 seconds
       Maximum number of seconds to run all queries: 0.009 seconds
       Number of clients running queries: 1
       Average number of queries per client: 0

mysqlslap meldet einige Benchmarking-Statistiken, wie in der Ausgabe gezeigt. Es gibt die durchschnittliche, minimale und maximale Anzahl von Sekunden an, die zum Ausführen der Abfrage benötigt wurden. Wir können auch sehen, dass die Anzahl der für diesen Auslastungstest verwendeten Clientverbindungen eins betrug.

Versuchen Sie nun 50 gleichzeitige Verbindungen und lassen Sie die automatisch generierte Abfrage zehnmal ausführen:

sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=50 --iterations=10 --auto-generate-sql --verbose

Dieser Befehl bedeutet, dass fünfzig simulierte Clientverbindungen dieselbe Testabfrage zur selben Zeit auslösen und dieser Test zehnmal wiederholt wird.

Die Ausgabe zeigt uns einen deutlichen Unterschied zur erhöhten Belastung:

Benchmark
       Average number of seconds to run all queries: 0.197 seconds
       Minimum number of seconds to run all queries: 0.168 seconds
       Maximum number of seconds to run all queries: 0.399 seconds
       Number of clients running queries: 50
       Average number of queries per client: 0

Beachten Sie, wie das Feld jetzt einen Wert von 50 anzeigt. Die durchschnittliche Anzahl von Abfragen pro Client beträgt null.

Automatisch generiertes SQL erstellt eine einfache Tabelle mit zwei Feldern. In den meisten Produktionsumgebungen sind die Tabellenstrukturen viel größer. Wir können mysqlslap anweisen, dies zu emulieren, indem wir der Testtabelle zusätzliche Felder hinzufügen. Dazu können wir zwei neue Parameter verwenden: + - number-char-cols + und + - number-int-cols +. Diese Parameter geben die Anzahl der varchar- und int-Spaltentypen an, die der Testtabelle hinzugefügt werden sollen.

Im folgenden Beispiel testen wir mit einer automatisch generierten SQL-Abfrage, die für eine Tabelle mit 5 numerischen Spalten und 20 Zeichentypspalten ausgeführt wird. Wir simulieren außerdem 50 Client-Verbindungen und möchten, dass der Test 100 Mal wiederholt wird:

sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=50 --iterations=100 --number-int-cols=5 --number-char-cols=20 --auto-generate-sql --verbose

Dieser sollte etwas länger dauern. Während der Test ausgeführt wird, können wir zum anderen Terminalfenster wechseln, in dem eine MySQL-Sitzung ausgeführt wird, und sehen, was los ist. Beachten Sie, dass der Test abgeschlossen wird, wenn Sie zu lange warten und die Testdatenbank nicht angezeigt wird.

Von der MySQL-Eingabeaufforderung aus:

show databases;

Beachten Sie die Datenbank:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| mysqlslap          |
| performance_schema |
+--------------------+
5 rows in set (0.01 sec)

Sie können die Tabelle in der Testdatenbank überprüfen, wenn Sie möchten. es heißt * t1 *.

Überprüfen Sie erneut Ihr anderes Terminalfenster. Wenn der Test abgeschlossen ist, werden Sie feststellen, dass sich die Leistung mit der erhöhten Last noch weiter verlangsamt hat:

Benchmark
       Average number of seconds to run all queries: 0.695 seconds
       Minimum number of seconds to run all queries: 0.627 seconds
       Maximum number of seconds to run all queries: 1.442 seconds
       Number of clients running queries: 50
       Average number of queries per client: 0

Kehren Sie zu Ihrer MySQL-Terminalsitzung zurück. Wir können sehen, dass mysqlslap seine Wegwerfdatenbank gelöscht hat. An der MySQL-Eingabeaufforderung:

show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)

Anwendungsfall: Benchmarking mit benutzerdefinierten Abfragen

Automatisch generiertes SQL ist gut, wenn Sie die physischen Ressourcen des Servers evaluieren. Dies ist hilfreich, wenn Sie die Auslastung eines bestimmten Systems ermitteln möchten.

Wenn Sie Leistungsprobleme für eine bestimmte datenbankabhängige Anwendung beheben möchten, möchten Sie jedoch echte Abfragen für echte Daten testen. Diese Abfragen stammen möglicherweise von Ihrem Web- oder Anwendungsserver.

Im Moment gehen wir davon aus, dass Sie die spezifische Abfrage kennen, die Sie testen möchten. Im nächsten Abschnitt zeigen wir Ihnen, wie Sie nach Abfragen suchen, die auf Ihrem Server ausgeführt werden.

Wir beginnen mit Inline-Abfragen. Mit dieser Option können Sie mysqlslap eine Inline-Abfrage geben. Die SQL-Anweisungen dürfen keine Zeilenumbrüche enthalten und müssen durch Semikolons (;) getrennt sein. Die Abfragen müssen auch in doppelte Anführungszeichen eingeschlossen werden.

Im folgenden Codeausschnitt führen wir eine einfache Abfrage für die Tabelle aus. Die Tabelle "deptemp" enthält mehr als dreihunderttausend Datensätze. Beachten Sie, wie wir die Datenbank mit der Option angegeben haben:

sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=50 --iterations=10 --create-schema=employees --query="SELECT * FROM dept_emp;" --verbose

Das wird eine Weile dauern. Sie sollten nach ein oder zwei Minuten einen solchen Leistungsbenchmark erhalten:

Benchmark
       Average number of seconds to run all queries: 18.486 seconds
       Minimum number of seconds to run all queries: 15.590 seconds
       Maximum number of seconds to run all queries: 28.381 seconds
       Number of clients running queries: 50
       Average number of queries per client: 1

(Hinweis: Wenn diese Abfrage länger als zehn Minuten hängt oder keine Ausgabe liefert, sollten Sie sie mit einer niedrigeren Zahl für und / oder erneut versuchen oder auf einem größeren Server versuchen.)

Als Nächstes verwenden wir mehrere SQL-Anweisungen im Parameter. Im folgenden Beispiel beenden wir jede Abfrage mit einem Semikolon. mysqlslap weiß, dass wir mehrere separate SQL-Befehle verwenden, weil wir die Option angegeben haben:

sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=20 --iterations=10 --create-schema=employees --query="SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;" --delimiter=";" --verbose

Dieser Test verwendet die gleiche Anzahl von Verbindungen und die gleiche Anzahl von Iterationen. Bei mehreren SELECT-Anweisungen war die Leistung jedoch inkrementell langsamer (durchschnittlich 23,8 Sekunden gegenüber 18,486 Sekunden):

Benchmark
       Average number of seconds to run all queries: 23.800 seconds
       Minimum number of seconds to run all queries: 22.751 seconds
       Maximum number of seconds to run all queries: 26.788 seconds
       Number of clients running queries: 20
       Average number of queries per client: 5

Produktions-SQL-Anweisungen können kompliziert sein. Es ist einfacher, einem Skript eine komplizierte SQL-Anweisung hinzuzufügen, als sie für Tests einzugeben. Daher können wir mysqlslap anweisen, die Abfrage aus einer Skriptdatei zu lesen.

Um dies zu veranschaulichen, erstellen wir eine Skriptdatei aus den SQL-Befehlen. Wir können das folgende Code-Snippet verwenden, um eine solche Datei zu erstellen:

sudo echo "SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;" > ~/select_query.sql

sudo cp ~/select_query.sql /mysqlslap_tutorial/

Die Datei enthält jetzt alle fünf SELECT-Anweisungen.

Da dieses Skript mehrere Abfragen enthält, können wir ein neues Testkonzept einführen. mysqlslap kann die Abfragen parallelisieren. Wir können dies tun, indem wir die Anzahl der Abfragen angeben, die jeder Testclient ausführen soll. mysqlslap macht das mit der Option. Wenn also 50 Verbindungen und 1000 Abfragen ausgeführt werden müssen, führt jeder Client jeweils ca. 20 Abfragen aus.

Schließlich können wir auch den Schalter verwenden, der uns einen Hinweis auf die verwendeten Rechenressourcen gibt.

Im folgenden Codeausschnitt bitten wir mysqlslap, die soeben erstellte Skriptdatei zu verwenden. Wir spezifizieren auch den Parameter. Der Vorgang wird zweimal wiederholt und wir möchten Debugging-Informationen in der Ausgabe erhalten:

sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=20 --number-of-queries=1000 --create-schema=employees --query="/mysqlslap_tutorial/select_query.sql" --delimiter=";" --verbose --iterations=2 --debug-info

Nach Abschluss dieses Befehls sehen wir einige interessante Ergebnisse:

Benchmark
       Average number of seconds to run all queries: 217.151 seconds
       Minimum number of seconds to run all queries: 213.368 seconds
       Maximum number of seconds to run all queries: 220.934 seconds
       Number of clients running queries: 20
       Average number of queries per client: 50


User time 58.16, System time 18.31
Maximum resident set size 909008, Integral resident set size 0
Non-physical pagefaults 2353672, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 102785, Involuntary context switches 43

Hier beträgt die durchschnittliche Anzahl von Sekunden, um alle Abfragen in unserer MySQL-Instanz auszuführen, 217 Sekunden, fast 4 Minuten. Dies hing sicherlich mit der Größe des für unsere virtuelle Maschine verfügbaren Arbeitsspeichers und der CPU zusammen, war jedoch auch auf die große Anzahl von Abfragen durch eine moderate Anzahl von Clientverbindungen zurückzuführen, die zweimal wiederholt wurden.

Wir können sehen, dass es eine große Anzahl von nicht-physischen Seitenfehlern gab. Seitenfehler treten auf, wenn keine Daten im Speicher gefunden werden und das System sie aus der Auslagerungsdatei auf der Festplatte abrufen muss. Die Ausgabe zeigt auch CPU-bezogene Informationen. In diesem Fall sehen wir eine große Anzahl von Kontextwechseln.

Anwendungsfall: Praktisches Benchmarking-Szenario und Erfassen von Live-Abfragen

Bisher haben wir in unseren Beispielen Abfragen für die ursprüngliche Mitarbeiterdatenbank ausgeführt. Das ist etwas, was DBAs sicherlich nicht möchten, dass Sie es tun. Und dafür gibt es einen guten Grund. Sie möchten nicht hinzufügen, dass Ihre Produktionsdatenbank geladen wird, und Sie möchten keine Testabfragen ausführen, mit denen Daten in Ihre Produktionstabellen gelöscht, aktualisiert oder eingefügt werden können.

Wir zeigen Ihnen, wie Sie eine Sicherungskopie einer Produktionsdatenbank erstellen und in eine Testumgebung kopieren. In diesem Beispiel befindet es sich auf demselben Server, aber Sie würden es idealerweise auf einen separaten Server mit derselben Hardwarekapazität kopieren.

Noch wichtiger ist, dass wir Ihnen zeigen, wie Sie Abfragen live aus der Produktionsdatenbank aufzeichnen und sie einem Testskript hinzufügen. Das heißt, Sie erhalten Abfragen aus der Produktionsdatenbank, führen jedoch Tests für die Testdatenbank aus.

Die allgemeinen Schritte lauten wie folgt und können für jeden mysqlslap-Test verwendet werden:

  • 1. * Kopieren Sie die Produktionsdatenbank in eine Testumgebung. + 2. Konfigurieren Sie MySQL so, dass alle Verbindungsanfragen und Abfragen in der Produktionsdatenbank aufgezeichnet und aufgezeichnet werden. + * 3. * Simulieren Sie den Anwendungsfall, den Sie testen möchten. Wenn Sie beispielsweise einen Einkaufswagen ausführen, sollten Sie etwas kaufen, um alle entsprechenden Datenbankabfragen in Ihrer Anwendung auszulösen. + * 4. * Deaktivieren Sie die Abfrageprotokollierung. + * 5. * Sehen Sie sich das Abfrageprotokoll an und erstellen Sie eine Liste der Abfragen, die Sie testen möchten. + * 6. * Erstellen Sie eine Testdatei für jede Abfrage, die Sie testen möchten. + * 7. * Führen Sie die Tests aus. + * 8. * Verwenden Sie die Ausgabe, um die Leistung Ihrer Datenbank zu verbessern.

Zunächst erstellen wir ein Backup der Mitarbeiterdatenbank. Wir erstellen ein separates Verzeichnis für die Sicherung:

sudo mkdir /mysqlslap_tutorial/mysqlbackup

cd /mysqlslap_tutorial/mysqlbackup

Erstellen Sie das Backup und verschieben Sie es in das neue Verzeichnis:

sudo mysqldump --user sysadmin --password --host localhost employees > ~/employees_backup.sql

sudo cp ~/employees_backup.sql /mysqlslap_tutorial/mysqlbackup/

Gehen Sie zu Ihrem MySQL-Testserver. Erstellen Sie die Datenbank:

CREATE DATABASE employees_backup;

Wenn Sie zu diesem Zeitpunkt einen separaten Server zum Testen verwenden, sollten Sie die Datei auf diesen kopieren. Importieren Sie die Sicherungsdaten von Ihrer Hauptterminalsitzung in die Datenbank:

sudo mysql -u sysadmin -p employees_backup < /mysqlslap_tutorial/mysqlbackup/employees_backup.sql

Aktivieren Sie auf Ihrem * produktiven MySQL-Datenbankserver * das allgemeine MySQL-Abfrageprotokoll, und geben Sie einen Dateinamen für dieses Protokoll an. Das allgemeine Abfrageprotokoll erfasst Verbindungs-, Trennungs- und Abfrageaktivitäten für eine MySQL-Datenbankinstanz.

SET GLOBAL general_log=1, general_log_file='capture_queries.log';

Führen Sie nun die Abfragen, die Sie testen möchten, auf dem Produktions-MySQL-Server aus. In diesem Beispiel führen wir eine Abfrage über die Befehlszeile aus. Möglicherweise möchten Sie jedoch Abfragen aus Ihrer Anwendung generieren, anstatt sie direkt auszuführen. Wenn Sie einen langsamen Prozess oder eine langsame Webseite haben, die Sie testen möchten, sollten Sie diesen Prozess durchlaufen oder jetzt auf diese Webseite zugreifen. Wenn Sie beispielsweise einen Einkaufswagen ausführen, möchten Sie möglicherweise den Checkout-Vorgang jetzt abschließen, wodurch alle entsprechenden Abfragen auf dem Datenbankserver ausgelöst werden.

Dies ist die Abfrage, die wir auf dem MySQL-Produktionsserver ausführen. Verwenden Sie zuerst die richtige Datenbank:

USE employees;

Führen Sie nun die Abfrage aus:

SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN  dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY  e.first_name, e.last_name, d.dept_name, t.from_date;

Erwartete Ausgabe:

489903 rows in set (4.33 sec)

Die allgemeine Protokollierung wird deaktiviert, wenn die Abfrage abgeschlossen ist:

SET GLOBAL general_log=0;

Beachten Sie, dass beim Verlassen der Protokollierung weiterhin Abfragen zum Protokoll hinzugefügt werden, was das Testen möglicherweise erschwert. Stellen Sie daher sicher, dass Sie das Protokoll sofort nach Abschluss des Tests deaktivieren. Überprüfen wir, ob die Protokolldatei im Verzeichnis erstellt wurde:

sudo ls -l /var/lib/mysql/capt*

-rw-rw----. 1 mysql mysql 861 Sep 24 15:09 /var/lib/mysql/capture_queries.log

Kopieren Sie diese Datei in unser MySQL-Testverzeichnis. Wenn Sie zum Testen einen separaten Server verwenden, kopieren Sie diesen auf diesen Server.

sudo cp /var/lib/mysql/capture_queries.log /mysqlslap_tutorial/

In dieser Protokolldatei sollte sich eine ganze Menge Daten befinden. In diesem Beispiel sollte die gewünschte Abfrage fast fertig sein. Überprüfen Sie den letzten Teil der Datei:

sudo tail /mysqlslap_tutorial/capture_queries.log

Erwartete Ausgabe:

        6294 Query show databases
        6294 Query show tables
        6294 Field List    departments
        6294 Field List    dept_emp
        6294 Field List    dept_manager
        6294 Field List    employees
        6294 Field List    salaries
        6294 Field List    titles
140930 15:34:52  6294 Query SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN  dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY  e.first_name, e.last_name, d.dept_name, t.from_date
140930 15:35:06  6294 Query SET GLOBAL general_log=0

Dieses Protokoll zeigt SQL-Befehle und ihre Zeitstempel. Die SQL-Anweisung am Ende der Datei interessiert uns. Es sollte genau so aussehen wie der Befehl, den wir in der Produktionsdatenbank ausgeführt haben, da wir ihn dort erfasst haben.

In diesem Beispiel kannten wir die Abfrage bereits. In einer Produktionsumgebung kann diese Methode jedoch sehr nützlich sein, um Abfragen zu finden, von denen Sie möglicherweise nicht wissen, dass sie auf Ihrem Server ausgeführt werden.

Beachten Sie, dass diese Datei völlig anders aussieht, wenn Sie während der Protokollierung unterschiedliche Abfragen ausgeführt oder ausgelöst haben. In einem realen Szenario könnte diese Datei mit Hunderten von Einträgen überflutet werden, die von allen verschiedenen Verbindungen stammen. Ihr Ziel ist es, die Abfragen zu finden, die einen Engpass verursachen. Sie können zunächst eine Liste aller Zeilen erstellen, die den Text enthalten. Dann erhalten Sie eine Liste mit genau den Abfragen, die während des Tests in Ihrer Datenbank ausgeführt wurden.

Kopieren Sie jede Abfrage, die Sie testen möchten, in eine Datei, die mit der Erweiterung "+ .sql +" endet.

Zum Beispiel:

sudo vi /mysqlslap_tutorial/capture_queries.sql

Der Inhalt sollte die MySQL-Abfrage sein, die Sie testen möchten, ohne Zeilenumbrüche und ohne Semikolon am Ende:

SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN  dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY  e.first_name, e.last_name, d.dept_name, t.from_date

Stellen Sie als Nächstes sicher, dass die Abfrageergebnisse nicht zwischengespeichert werden. Kehren Sie zu Ihrer * MySQL-Sitzung testen * zurück. Führen Sie den folgenden Befehl aus:

RESET QUERY CACHE;

Jetzt ist es an der Zeit, das Dienstprogramm mysqlslap mit der Skriptdatei auszuführen. Stellen Sie sicher, dass Sie den richtigen Skriptdateinamen im Parameter verwenden. Wir werden nur zehn gleichzeitige Verbindungen verwenden und den Test zweimal wiederholen. Führen Sie dies von Ihrem * Testserver * aus:

sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=10 --iterations=2 --create-schema=employees_backup --query="" --verbose

Die Benchmark-Ausgabe sieht in unserem System folgendermaßen aus:

Benchmark
       Average number of seconds to run all queries: 68.692 seconds
       Minimum number of seconds to run all queries: 59.301 seconds
       Maximum number of seconds to run all queries: 78.084 seconds
       Number of clients running queries: 10
       Average number of queries per client: 1

Wie können wir diesen Benchmark verbessern?

Sie benötigen eine gewisse Vertrautheit mit MySQL-Abfragen, um beurteilen zu können, was die Abfrage tut.

Wenn Sie auf die Abfrage zurückblicken, sehen Sie, dass sie mehrere Joins über mehrere Tabellen hinweg ausführt. Die Abfrage zeigt die Job-Historie der Mitarbeiter an und verknüpft dabei die verschiedenen Tabellen nach Feld. Das Feld wird auch zum Beitreten verwendet. Da es jedoch nur wenige Abteilungsdatensätze gibt, werden wir dies ignorieren. Da die Datenbank viele Einträge enthält, ist es logisch anzunehmen, dass das Erstellen von Indizes für das Feld die Abfrage verbessern kann.

Mit ein wenig Übung können Sie, sobald Sie Abfragen gefunden haben, die den Server belasten (das ist der Teil, bei dem mysqlslap hilft!), Beurteilungen zu den Abfragen vornehmen, die auf Ihren Kenntnissen von MySQL und Ihrer Datenbank basieren.

Als Nächstes können Sie versuchen, Ihre Datenbank oder die darin ausgeführten Abfragen zu verbessern.

In unserem Fall fügen wir die oben genannten Indizes hinzu. Wir werden drei Indizes für erstellen. Ein Index wird für das Feld in der Tabelle erstellt, ein weiterer Index für das Feld in der Tabelle und der letzte Index für das Feld in der Tabelle.

Gehen wir zu unserer Test-MySQL-Sitzung und führen Sie die folgenden Befehle aus:

USE employees_backup;

CREATE INDEX employees_empno ON employees(emp_no);

CREATE INDEX dept_emp_empno ON dept_emp(emp_no);

CREATE INDEX titles_empno ON titles(emp_no);

Wenn wir zu unserem Hauptterminalfenster auf dem Testserver zurückkehren und mysqlslap mit denselben Parametern ausführen, werden wir einen Unterschied im Benchmark feststellen:

sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=10 --iterations=2 --create-schema=employees_backup --query="/mysqlslap_tutorial/capture_queries.sql" --verbose
Benchmark
       Average number of seconds to run all queries: 55.869 seconds
       Minimum number of seconds to run all queries: 55.706 seconds
       Maximum number of seconds to run all queries: 56.033 seconds
       Number of clients running queries: 10
       Average number of queries per client: 1

Wir können sehen, dass sich die durchschnittliche, minimale und maximale Ausführungszeit der Abfrage sofort verbessert. Anstelle von durchschnittlich 68 Sekunden wird die Abfrage jetzt in 55 Sekunden ausgeführt. Das ist eine Verbesserung von 13 Sekunden bei gleicher Ladung.

Da diese Datenbankänderung in der Testumgebung zu einem guten Ergebnis geführt hat, können Sie sie jetzt auf Ihren Produktionsdatenbankserver übertragen. Beachten Sie jedoch, dass Datenbankänderungen in der Regel Nachteile in Bezug auf ihre Vor- und Nachteile haben.

Sie können das Testen von Befehlen und Verbesserungen mit allen Abfragen wiederholen, die Sie aus Ihrem Protokoll abgerufen haben.

Fehlerbehebung - mysqlslap zeigt keine Ausgabe an

Wenn Sie einen Testbefehl ausführen und keine Ausgabe erhalten, ist dies ein guter Hinweis darauf, dass die Serverressourcen maximal genutzt werden könnten. Zu den Symptomen gehören ein Fehlen der Ausgabe oder ein Fehler wie "+ mysqlslap: Fehler beim Speichern des Ergebnisses: 2013 Die Verbindung zum MySQL-Server wurde während der Abfrage unterbrochen".

Möglicherweise möchten Sie den Test mit einer kleineren Zahl im Parameter oder wiederholen. Alternativ können Sie versuchen, Ihre Testserverumgebung zu aktualisieren.

Auf diese Weise können Sie die äußeren Grenzen der Kapazität Ihres Datenbankservers ermitteln.

Fazit

mysqlslap ist ein einfaches, leichtgewichtiges Tool, das einfach zu bedienen ist und sich direkt in die MySQL-Datenbank-Engine einfügt. Es ist für alle Editionen von MySQL ab Version 5.1.4 verfügbar.

In diesem Tutorial haben wir gesehen, wie man mysqlslap mit seinen verschiedenen Optionen benutzt und mit einer Beispieldatenbank herumgespielt. Sie können andere Beispieldatenbanken von der MySQL-Site herunterladen und mit diesen auch üben. Wie bereits erwähnt, * führen Sie bitte keine Tests auf einem Produktionsdatenbankserver durch. *

Der letzte Anwendungsfall in diesem Lernprogramm betraf nur eine Abfrage. Während wir die Leistung dieser Abfrage etwas verbessert haben, indem wir allen drei Tabellen zusätzliche Indizes hinzugefügt haben, ist der Vorgang im wirklichen Leben möglicherweise nicht so einfach. Das Hinzufügen zusätzlicher Indizes kann unter Umständen die Systemleistung beeinträchtigen, und Datenbankadministratoren müssen häufig die Vorteile des Hinzufügens eines zusätzlichen Index gegenüber den möglicherweise anfallenden Leistungskosten abwägen.

Testszenarien im realen Leben sind komplexer, aber dies sollte Ihnen die Werkzeuge bieten, um mit dem Testen und Verbessern Ihrer Datenbankleistung zu beginnen.