flog

dem Flo sein Blog

Ex-Feuerwehrman, Baskettballer, Schachspieler, House-Addict (since 1998), Radfahrer, Fitnessmensch und vor allem: Webprogrammierer aus Leidenschaft. Meine Hosen hab ich auch auf Facebook und Xing runtergelassen

MySQL Performance Tuning: Features / Learings

MySQL 5.1 Stable, Wann?

6. Dezember 2008, dieses Blog läuft jetzt aber schon auf 5.1

Kickfire, Magie, technische Raffinesse, oder Manpower?

Der "SQL-Chip" macht hier und da etwas Caching, hinter der Maschine steckt aber eigentlich nur brachiale Gewalt. Ein System mit ähnlicher Hardware (2 Quad Xeons, 16 GB Ram, SAS Platten, ...) wird ähnliche Benchmarks erreichen

Prepared Statements vs. Query Cache

Seit 5.1.17 wandern auch Prepared Statements in den Query-Cache. Diese Limitierung war besonders ärgerlich, da Prepared-Statements einem eine Menge Ärger ersparen können (Stichwort SQL-Injection), aber dadurch, dass die Ergebnisse nicht im Query-Cache landen, machen diese die Applikation langsamer im Vergleich zu "normalen" Queries.

"The query cache is not used for server-side prepared statements before MySQL 5.1.17. If you are using server-side prepared statements, consider that these statements will not be satisfied by the query cache." (Quelle)

Transaktion pro Sekunde

Jede abgeschlossene Transaktion (COMMIT) muss auf die Platte raus schreiben, dass bedeutet, pro COMMIT einmal write auf die Platte. Die mittlere Zugriffszeit ist eine Plattenumdrehung also lautet die Formel rein von der Spindel in der Platte: 1/(RPM/60) = Zugriffszeit. Bsp. 15.000 rpm: 1/(15000/60) = 0,004 s = 4ms
Das braucht schon alleine die Spindel / der Schreibkopf in der Platte um an der richtigen Position zu sein (im Schnitt).
Das bedeutet, dass pro Sekunde 250 Operationen auf die Platte durchgehen, mehr schafft die nicht (1/0,004 = 250). Alles mit mehr als 250 Transaktionen pro Sekunde wird also ein großer Spaß, vor allem: Das ist ein theoretischer Wert. Das Betriebssystem muss ja auch noch was machen.

Umkreissuche

Du bist an Punkt X und suchst alle Objekte im Umkreis von Y Kilometer. Ob ein Punkt innerhalb deines Umkreises ist ließe sich ganz einfach mit < a href="http://de.wikipedia.org/wiki/Satz_des_Pythagoras">Satz des Pythagoras berechnen. Problem: Du musst für jeden Punkt in der Datenbank eine komplexe Berechnung ausführen. Beispiel: X = (100/200) y = 30. Für jeden Punkt, der innerhalb des Umkreises ist gilt:

(100-x)^2 + (200-y)^2 <= 30^2
Das Problem hierbei: Ein Full-Table Scan. Was tun? Vorselektieren. Wie? Ein Viereck aufspannen:
x BETWEEN 100-30 AND 100+30
AND y BETWEEN 200-30 AND 200+30
Das lässt sich auch noch mit einem Index beschleunigen und ist zumindest ein Näherungswert. Dann per AND einfach noch die Bedinung von oben dran flanschen:
SELECT foo
FROM bar
WHERE x BETWEEN 100-30 AND 100+30
AND y BETWEEN 200-30 AND 200+30
AND POW(100-x,2)+POW(200-y,2) <= 30^2

MySQL Clipping-Feature Abschlaten

Seit MySQL 5.1 gibt es die Möglichkeit, das Clipping-Feature abzuschalten. Clipping ist dafür verantwortlich, dass man in ein TinyInt Feld zwar 300 reinschreibt, dann aber nur 255 drin steht, oder dass man einen String mit der Länge von z.B. 12 in ein CHAR(10) Feld speichern kann, dann aber halt einfach nur 10 Zeichen drin stehen. Kurz gesagt: Clipping ist Scheiße. Und das lässt sich abschalten:

SET GLOBAL SQL_MODE=STRICT_ALL_TABLES;
Dann macht MySQL kein Clipping mehr, sondern quitiert die Operation mit einer Fehlermeldung.
MySQL Doku

InnoDB Threads

InnoDB arbeitet intern mit mehrere Threads. Allerdings ist die Standardeinstellung so gewählt, dass nur maximal acht Threads gleichzeitig arbeiten können, alle anderen warten. Um das zu ändern muss man die Variable "innodb_thread_concurrency" einstellen. Faustformel für einen guten Wert: Anzahl_Cores * Anzahl_Platten * 2
Wobei Anzahl Platten die Platten sind, auf welchen das InnoDB-Datafile liegt (Stripping).

MySQL Schulung: Performance Tuning

Erster Tag

Es ist gerade kurze Pause, hier also mal in Kurzform, was bisher geschah:

  • 03:00 Wecker klingelt
  • 03:50 Aufstehen und ab ins Bad (es wird höchste Zeit)
  • 04:15 Raus aus dem Haus zur Bushaltestelle Stadtmitte
  • 04:49 Pünktlich ist der X3 in Reutlingen, hoffentlich auch so pünktlich in Stuttgart am Flughafen
  • 05:40 Mit kleiner Verspätung bin ich am Flughafen, schnell zum AirBerlin Check-In
  • 05:50 Ich hab die Boardingkarte in meiner Hand, jetzt zum Gate und noch schnell die aktuelle c't kaufen
  • 06:10 Ich sitz am Gate, Boarding sollte schon laufen, verspätet sich scheinbar etwas heute.
  • 06:15 Zwei junge Mädchen kommen angehastet, haben das mit der Zeitumstellung scheinbar verpasst und wollten wissen, ob der Flug schon weg ist ;-)
  • 06:20 Boarding
  • 06:30 Ich sitze am Fenster, vorletzte Reihe und kann beim Start die Lichterschlange bewundern, die sich die B28 nach Stuttgart quält
  • 07:33 Landung in Berlin-Tegel, trübes Wetter, es nieselt, wir fahren mit dem Bus zur Gepäckausgabe
  • 08:00 Mit der Tasche auf dem Rücken gehts zum Bus, dann mit der U-Bahn zum Checkpoint-Charlie
  • 08:40 Einchecken im Hotel: Wow, ich konnte sogar mit Bad statt Dusche wählen. Aber keine Zeit mehr fürs Zimmer, auf zum Schulungszentrum
  • 08:58 Yehaw, noch rechtzeitig geschafft, unterwegs sogar noch zwei Päckchen Taschentücher für jeweils 10 Cent gekauft

Mittagspause: Mittagessen in der Axel-Springer Kantine (ja, der Axel Springer) und festgestellt, dass mein Hotel vier Sterne hat und eine Tageskarte Sauna und Wellnessbereich 10 € kostet. Das werde ich mir auf jeden Fall noch gönnen in der Hoffnung, dass man mir Bademantel und Handtuch stellt.

Zur Schulung selber: Der Dozent hat echt was drauf, arbeitet selber für Sun (dem Eigentümer von MySQL, falls das jemand noch nicht mitbekommen hat ;-)) und hat eine echt gute Art, sein Wissen rüber zu bringen.

Erster Tag zu Ende und wir sind sogar 20 Minuten früher mit dem Stoff fertig geworden als geplant. Kurz zum Dozenten noch was: Er hat früher in einer Internet-Agentur gearbeitet und hat damals den Session-Support für PHP gehakt. Arbeitet seit ein paar Jahren für MySQL AB (inzwischen zu Sun gehörend) und hält Schulungen und Vorträge auf diversen Veranstaltungen.

Zweiter Tag

Heute morgen um 06:30 Uhr kam der Weckruf, allerdings nicht der vom Hotel (der war auf 07:00 Uhr bestellt), sondern der von meiner Mutter. Ich hab dann noch Nachrichten geschaut, mich danach geduscht, frisch gemacht, einen kurzen Abstecher in den Saunabereich (nur um mal zu schauen, was denn da so wäre) und dann raus aus dem Hotel, ab zur Bäckerei Kamps (die liegt direkt auf dem Weg) und erst mal was zum Frühstücken organisiert und dann auf hier her ins Schulungszentrum. Ein StarBucks Kaffee liegt auch hier auf dem Weg, dass muss werde schon mal ausprobieren.

Zur Schulung: Im "Student Guide" hab ich gelesen, dass wir neben den üblichen Dingen (Schema/Datenbank Design, Indexing, Statement Tuning) auch die Storage Engines durchsprechen werden. Dabei gibt es natürlich für MyISAM und InnoDB eigene Kapitel aber auch die neue, mit MySQL 6 kommende Falcon wird ein großes Thema sein.

Der Dozent ist auch da, die Klasse vollständig, ich meld mich später wieder mit Updates.

Mittagspause, wieder lecker in der Axel Springer Kantine, diese Woche ist "Schnitzeljagd" jeden Tag ein anderes Schnitzel, heute mit Käse und Zwiebeln überbacken und Pommes. Wunderbar. Den Dozenten mal auf Kickfire angesprochen. Das hat nichts mit technischer Raffinesse zu tun, viel mehr mit brachialer Gewalt, dieser "SQL-Prozessor" machst nichts weiter als hier und da Cachen, aber ansonsten ist das Ding einfach nur schnell, wegen zwei Quad-Core Xeon`s, 16 GB Ram, SAS Platten ...

Gestern Nachmittag dann noch sehr spannende Themen: Umkreissuche mit MySQL, wie macht XING das mit dem "Sie kennen Person X über" eigentlich, MySQL Indexing und Caching (ja, Prepared Statements werden seit MySQL 5.1.17 auch in den Query-Cache gelegt).

Abends ging es dann noch mit dem Dozenten und einem anderen Kursteilnehmer in die "Hackeschen Höfe" eine Berliner Weiße trinken. War ganz ok, eine reicht dann aber auch. Abends bin ich dann in meinem Hotel noch in die Sauna gegangen, drei Saunagänge in annähernd zweieinhalb Stunden.

Dritter Tag

Heute morgen kam wieder ein privater Weckruf, diesmal allerdings schon um kurz nach vier von meiner Frau, sie geht jetzt zur Arbeit (Frühschicht im Altenheim). Ich hab ihr von dem Hotel und der Sauna und dem Kurs vorgeschwärmt, alles perfekt hier. Danach hab ich mich wieder schlafen gelegt, weil ja um sieben der Weckruf vom Hotel kommt. Den hab ich dann auch gehört, aufgestanden, frisch gemacht, Richtung Schulungszentrum marschiert, unterwegs noch was zum Frühstück gekauft und an der Ampel den anderen Kursteilnehmer von gestern Abend wieder getroffen. Zusammen sind wir dann die restlichen 300m zum Schulungszentrum gelaufen. Heute geht es im Kurs weiter mit Server-Konfiguration und dem Thema MyISAM und INNODB.

Wow, man kann MySQL dieses Clipping abgewöhnen. Das "Feature", dass dafür sorgt, dass man eine 300 in ein TinyInt (max. 255) schreiben kann und dann aber einfach 255 drin steht, oder das beim schreiben in ein CHAR Feld, einfach der Rest, der nicht reinpasst abgeschnitten wird, kommentarlos. Der Zauberbefehl lautet: SET GLOBAL SQL_MODE=STRICT_ALL_TABLES;
Dann bekommt man eine Fehlermeldung geliefert. MySQL 5.1 machts möglich.

Wir haben dann noch die Innereien von MyISAM und InnoDB besprochen, InnoDB machen wir morgen noch gar fertig und dann wollen wir einen MySQL-Cluster aufsetzen, gehört zwar nicht zum Kurs, aber wir haben die Zeit und es macht Laune sagt der Dozent.

Vierter (letzter) Tag

Aus dem Hotel ausgecheckt, und ab ins Schulungszentrum. Die Vorfreude auf den Cluster und Falcon wächst :-)

So, InnoDB noch einiges gelernt. Da gibt es noch einige Features, die ich nicht kannte, bzw. die man einstellen sollte, ja sogar muss. Falcon haben wir uns nur kurz angeschaut, weil wir a) keine 6er MySQL hier installiert hatten und b) im allgemeinen mehr Interesse an dem Cluster bestand. Clustering haben wir dann besprochen und auch hier zum Laufen bekommen, das ging echt ratz fatz. Außerdem haben wir eine Buchempfehlung bekommen zum Thema Bäume in SQL: Joe Celko's Trees and Hierarchies in SQL for Smarties

Empfehlungen für weiterführende Kurse: Der MySQL High Availability kurs (weil Cluster und Replikation drin durchgesprochen wird) und das MySQL Boot Camp (von Morgens acht bis Abends acht alles um MySQL).

Tipp!

Der Kurs wird nicht günstiger, nur dadurch, dass er in Deutschland stattfindet. Folgendes Beispiel:

Ort Kosten Flug Hotel Gesamt
Berlin 1599 € 190 € 235 € 2024 €
Beijing (Peking) US$ 999 (~ 790 €) 800 € (ca.) 400 € (ca.) 1992 €

Der Dozent hat uns Empfohlen, dass wir das genau prüfen sollten, denn z.B. Kuala Lumpur, Neu Deli, usw. sind sehr günstig, vor allem durch den Wechselkurs zum Dollar. Die Mehrkosten für den Flug sind alleine dadurch schon wieder drin und das Hotel ist in der Regel günstiger (bzw. bei gleichem Geld eine höherer Standard). Das lässt sich dann auch prima mit Urlaub kombinieren und man spart sich gleich noch was dabei. Die Dozenten sind dort nicht von vor Ort, sondern kommen von irgendwo her, er selbst hat auch schon mehrmals Schulungen in Asien gehalten.

Berlin, Berlin, wir fahren nach Berlin

Am Montag morgen geht es los. MySQL Performance-Tuning Schulung in Berlin. Montag morgen per AirBerlin nach Tegel, Übernachtung im Hotel um die Ecke und Donnerstag Abend Rückflug von Tegel. Wenn Internet vorhanden, werde ich mich von dort melden.

Domainfactory vs. Server4You vs. Vanager [update 3]

Neulich kam eine E-Mail von Domainfactory. Dort hoste ich dieses Blog hier, nur Hosting, die kümmern sich um alles (kein vServer, kein Root-Server, ...). In dieser Mail stand drin, dass die MySQL-Server umgestellt werden. Und zwar sind die im Moment auf einem extra Server drauf und werden jetzt auf den Rechner gezogen, auf dem auch dein Web-Space liegt. Das soll mir Vorteile bringen. Tut es aber nicht, denn die Leistung, die vorher zwei Rechner erbracht haben, soll ab dann nur noch durch einen Rechner erbracht werden, was für mich bedeutet, dass ich zwar weiterhin den vollen Betrag monatlich abdrücken muss, aber weniger Leistung erhalte.

Aus so ziemlich diesem Grund bin ich damals von Host-Europe weg, weil da eben Datenbank und Web-Server auf der gleichen Maschine waren und da kam es dann regelmäßig am Wochenende dazu, dass die Datenbank nicht mehr erreichbar war.

Also hab ich mich entschieden, mal mit einem vServer zu spielen und zu sehen, was ich da so rausholen kann. Dazu bieten Server4You und Vanager kostenlose Testsysteme an, die exakten so eingestellt sind, wie der Server, den man später will. Server4You bietet vier Tage und Vanager sieben Tage Test an, ohne das es was kosten würde und ohne dass anschließend ein Vertrag anläuft. Nach dem Testzeitraum wird der vServer platt gemacht und ich komm einfach nicht mehr drauf, fertig.

Der Benchmark wird ausgeführt auf die Startseite meines Blogs, davon hab ich eine Kopie angefertig, die ich dann auf dem Server einspiele. Zum Test wird siege benutzt:

siege -t10s -c 100 -b http://URL/

Domainfactory

Läuft ja alles schon (MySQL5, Apache und PHP5, kein XCache), also hier die Ergebnisse:

  • Transactions: 386 hits
  • Availability: 100.00 %
  • Elapsed time: 9.74 secs
  • Data transferred: 7.83 MB
  • Response time: 1.28 secs
  • Transaction rate: 39.63 trans/sec
  • Throughput: 0.80 MB/sec
  • Concurrency: 50.64
  • Successful transactions: 386
  • Failed transactions: 0
  • Longest transaction: 6.55
  • Shortest transaction: 0.13

Server4You

Ich hab den Testzugang bei Server4You am 17.07.2008 gegen Mittag geordert, es kam dann auch sofort eine Mail, dass man sich nun darum kümmert und ich dann die Zugansdaten bekomme.

Am 21.07. kamen dann die Zugangsdaten zu dem Server. Drauf war ein Debian Sarge (3.1), welches ich erstmal auf ein Edge (4.0) aktualisiert hab. Nach dem ich beim ersten mal was falsch gemacht hab und die Maschine nicht mehr gebootet hat, hab ich im Backend einfach das 3.1er Debian wieder hergestellt und nochmal ein update gemacht. Nach dem Reboot ging das System dann. Danach erst mal mit Lighttpd, MySQL 5, PHP5 und XCache ausstatten und testen.

  • Transactions: 526 hits
  • Availability: 100.00 %
  • Elapsed time: 9.64 secs
  • Data transferred: 12.21 MB
  • Response time: 1.61 secs
  • Transaction rate: 54.56 trans/sec
  • Throughput: 1.27 MB/sec
  • Concurrency: 87.84
  • Successful transactions: 526
  • Failed transactions: 0
  • Longest transaction: 4.82
  • Shortest transaction: 0.21

Hardware: 15 GB Webspace, 1,5 TB Traffic, 384 MB-Ram (plus 768 MB FlexRam (wenn benötigt und verfügbar)), CPU 3x (was auch immer das heißt), Tarrif: vSERVER MEDIUM x2

Kosten: 7,85 € pro Monat die erste drei/sechs Monate, danach 16,85 €, keine Setupkosten

Vanager

Diesen Testzugang hab ich am 18.07.2008 gegen Mittag geordert, die Web-Seite zeigte mir dann an, dass ich demnächst (innerhalb von einer bis 72 Stunden) meine Zugangsdaten bekommen würde. Leider ist bis jetzt (22.07.) noch nichts gekommen, das Versprechen "Freischaltung innerhalb 1 - 72 Stunden" wurde leider nicht eingehalten, das hinterlässt schon mal keine guten Eindruck, aber gut, Server4You hat auch vier Tage gebraucht.

Eine Mail an den Support und schon hat es geklappt. Am 25.07. kamen meine Zugangsdaten. Ganz schick ist, dass da schon Debian 4.0 drauf ist, und ich nicht erst, wie bei Server4You das System updaten muss. Und dann folgte das gleiche wie bei Server4You: Ert mal den Server mit Lighttpd, MySQL 5, PHP5 und XCache ausstatten und testen, das Flog drauf laden und mit Siegen testen:

  • Transactions: 183 hits
  • Availability: 100.00 %
  • Elapsed time: 9.76 secs
  • Data transferred: 4.19 MB
  • Response time: 2.98 secs
  • Transaction rate: 18.75 trans/sec
  • Throughput: 0.43 MB/sec
  • Concurrency: 55.86
  • Successful transactions: 183
  • Failed transactions: 0
  • Longest transaction: 6.62
  • Shortest transaction: 0.24

Hardware: 16 GB Webspace, 600 GB Traffic, 384 MB Ram, 200% CPU (Was auch immer das heißt), Tarif: Profi.VPS (Linux)

Kosten: 14,99 € im Monat, 9,99 € Setupkosten

Fazit

Domainfactory liegt ziemlich in der Mitte, sowohl beim Preis, als auch bei der Leistung. Von Vanager hab ich mehr echt mehr versprochen, vor allem mehr Leistung. Wenn ich mich schon um den Server komplett selber kümmern muss, dann sollte der doch mehr Leistung bringen, als ein Homepage-Hosting, wo 300 Kunden sich einen Server teilen. Von Server4You war ich positiv überrascht, es ging eigentlich alles recht zügig, die Performance des Servers ist auch gut.

Update (27.07. 11:30)

Heute Nacht hat Domainfactory umgestellt und wie es nicht anders zu erwarten war, hier die aktuellen Benchmarks:

  • Transactions: 140 hits
  • Availability: 100.00 %
  • Elapsed time: 9.99 secs
  • Data transferred: 3.21 MB
  • Response time: 3.59 secs
  • Transaction rate: 14.01 trans/sec
  • Throughput: 0.32 MB/sec
  • Concurrency: 50.35
  • Successful transactions: 140
  • Failed transactions: 0
  • Longest transaction: 9.26
  • Shortest transaction: 0.15

Zusätzlich dazu ist es recht häufig jetzt schon vorgekommen, dass während des Benchmarks man nicht mehr auf die Seite drauf kommt, von wegen zu viele Verbindungen auf die Datenbank. Ganz schlecht. Deswegen werd ich da fristlos kündigen, mal sehen, ob die da mitmachen.

Update (24.09. 08:10)

Heute morgen hatte ich ein wenig Zeit, einen neuen Vanager Server zu testen. Gleiche Daten wie oben, der Benchmark lief aber deutlich besser:

  • Transactions: 931 hits
  • Availability: 100.00 %
  • Elapsed time: 10.02 secs
  • Data transferred: 24.16 MB
  • Response time: 0.20 secs
  • Transaction rate: 92.91 trans/sec
  • Throughput: 2.41 MB/sec
  • Concurrency: 18.50
  • Successful transactions: 931
  • Failed transactions: 0
  • Longest transaction: 6.12
  • Shortest transaction: 0.08

Mit 92 Hits/s ist Vanager damit absolute Nummer Eins. Die Frage, die ich jetzt noch habe ist: Warum war der Test-Server im ersten Test so miserabel schlecht?

Update (24.09. 14:05)

Da mit 2,4 MB/s meine Leitung am Limit war, hab ich nochmal gesieged, diesmal von einem Rechner aus, der mit 100Mbit/s angebunden ist:

  • Transactions: 1350 hits
  • Availability: 100.00 %
  • Elapsed time: 10.08 secs
  • Data transferred: 35.03 MB
  • Response time: 0.15 secs
  • Transaction rate: 133.93 trans/sec
  • Throughput: 3.48 MB/sec
  • Concurrency: 19.61
  • Successful transactions: 1350
  • Failed transactions: 0
  • Longest transaction: 3.13
  • Shortest transaction: 0.07

Perfekt