Für Tests ist es oft notwendig, größere Datenmengen in MySQL zu importieren. Abhängig von der Anzahl der INSERTs kann dies vor allem bei InnoDB sehr lange dauern, da jeder einzelne INSERT-Befehl in einer separaten Transaktion ausgeführt wird und MySQL wartet, bis diese per fsync() auf die Festplatte geschrieben wurden.
Im Produktionsbetrieb ist dieses Verhalten notwendig, um sicherzustellen, dass erfolgreich durchgeführte Transaktionen z.B. einen Stromausfall überdauern. Bei Testsystemen auf denen ausschließlich „Wegwerf“-Datenbanken verwendet werden oder beim initialen Einrichten von MySQL-Slaves, kann mit einem Trick etwas Zeit beim Import eingespart werden.
Hierzu gibt es die Library libeatmydata, die für bestimmte Anwendungen die fsync()-Funktionalität deaktiviert. Wie der Name schon andeutet, kann es hierbei zu Datenverlust und irreparabel beschädigten MySQL-Datenbanken kommen, wenn das System crasht, während die Library verwendet wird. Sie sollte daher nur mit Bedacht eingesetzt werden.
Zunächst muss der Sourcecode heruntergeladen und die Library kompiliert werden:
[code lang=“bash“]
# wget http://www.flamingspork.com/projects/libeatmydata/libeatmydata-9.tar.bz2
# tar xfj libeatmydata-9.tar.bz2
# cd libeatmydata-9
# make
gcc -shared -Wl,-soname,libeatmydata.so.1 -ldl -o libeatmydata.so.1.0 eatmydata.c -fPIC
ln -s libeatmydata.so.1.0 libeatmydata.so.1
ln -s libeatmydata.so.1 libeatmydata.so
gcc -o fsynctest fsynctest.c
[/code]
[code lang=“bash“]
# cp libeatmydata.so* /usr/lib
[/code]
Um die Library nun nutzen zu können, muss MySQL gestoppt und anschließend mit libeatmydata wieder gestartet werden:
[code lang=“bash“]
# service mysql stop
# LD_PRELOAD=/usr/lib/libeatmydata.so.1 mysqld &
# disown
[/code]
Mit Hilfe von pmap kann überprüft werden, ob libeatmydata auch wirklich verwendet wird:
[code lang=“bash“]
# pmap `pidof mysqld` | grep libeatmydata
00007fa534a2d000 4K r-x– /usr/lib/libeatmydata.so.1.0
00007fa534a2e000 2044K —– /usr/lib/libeatmydata.so.1.0
00007fa534c2d000 4K r—- /usr/lib/libeatmydata.so.1.0
00007fa534c2e000 4K rw— /usr/lib/libeatmydata.so.1.0
[/code]
Nach dem Import der Daten kann die Library wieder deaktiviert werden, indem MySQL ohne LD_PRELOAD-Umgebungsvariable neugestartet wird:
[code lang=“bash“]
# mysqladmin shutdown -uroot -p
# service mysql start
[/code]
Zum Abschluss noch einige Benchmarkergebnisse, die den Effekt von libeatmydata zeigen. Importiert wurden jeweils ein 2GB großer MySQL-Dump mit insgesamt ca. 30 Millionen Datensätzen:
ohne libeatmydata | 3 Stunden 12 Minuten |
mit libeatmydata | knapp über 6 Minuten |
Vielen Dank für den Tip, hat mir grad ne menge Zeit mit InnoDB bzw. XtraDB erspart 🙂
Gruß