Here we go again. This post walks through installing MySQL and running through some benchmarks to discover how best to utilise the SSDs and ZFS.
Installing MySQL
Naturally, the first thing you must do is install MySQL. There has been a lot of activity with Percona and MariaDB lately but we’ll stick with vanilla MySQL for the moment due to time constraints. We can drop in one of the other two later as required.
Advice for utilising an SSD in your MySQL deployment is pretty scattered and confusing. The best resource I’ve been able to find is this set of slides from Sun/MySQL.
Installing MySQL is a simple procedure using ports:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#[root@shana /]$ cd /usr/ports/databases/mysql55-server/
[root@shana /usr/ports/databases/mysql55-server]$ make install clean
# ===> Found saved configuration for mysql-server-5.5.25
# => mysql-5.5.25.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
#
# ===> Compressing manual pages for mysql-server-5.5.25
# ===> Registering installation for mysql-server-5.5.25
# ===> SECURITY REPORT:
# This port has installed the following files which may act as network
# servers and may therefore pose a remote security risk to the system.
# /usr/local/libexec/mysqld
#
# This port has installed the following startup scripts which may cause
# these network services to be started at boot time.
# /usr/local/etc/rc.d/mysql-server
#
# If there are vulnerabilities in these programs there may be a security
# risk to the system. FreeBSD makes no guarantee about the security of
# ports included in the Ports Collection. Please type 'make deinstall'
# to deinstall the port if this is a concern.
#
# For more information, and contact details about the security
# status of this software, see the following webpage:
# http://www.mysql.com/
# ===> Cleaning for cmake-2.8.8
# ===> Cleaning for mysql-client-5.5.25
# ===> Cleaning for mysql-server-5.5.25 |
Easy as that. You can enable MySQL (and leave the data directory in the default /var/db/mysql location) just by adding the following line to /etc/rc.conf.
mysql_enable="YES"
Then start it up:
|
1 |
[root@shana /]$ /usr/local/etc/rc.d/mysql start |
Benchmarking
For benchmarking MySQL we’ll use sysbench. In line with the PostgreSQL testing we did, we’ll create /mydbtmp and /mylogtmp drives in ZFS as they are required.
We’ll test the following scenarios, both with MyISAM and InnoDB (the most common engines).
- Running everything on zroot (Mirrored HDDs)
- Running everything on zflash (Mirrored SSDs)
- Running everything on zapps (Mirrored HDDs with SSD ZIL/L2ARC)
- Splitting the data and logs
We’ll look at ZFS optimisations after.
Setup
We repeat these steps for each benchmark. For our first three benchmarks we’ll only need /mydbtmp. Create it using ZFS:
|
1 |
[root@shana /]$ zfs create -o mountpoint=/mydbtmp/mydbtmp |
Substituting <pool> for zroot, zapps, and zflash as required.
To tell MySQL to use those data directories, add the following to your /etc/rc.conf:
mysql_datadir="/mydbtmp"
We will also need to create the mysql database and username:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[root@shana /]$ mysqladmin create sbtest
[root@shana /]$ mysql
#
# Welcome to the MySQL monitor. Commands end with ; or \g.
# Your MySQL connection id is 12
# Server version: 5.5.25 Source distribution
#
# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
#
# Oracle is a registered trademark of Oracle Corporation and/or its
# affiliates. Other names may be trademarks of their respective
# owners.
#
# Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create user 'sbtest'@'localhost';
# Query OK, 0 rows affected (0.00 sec)
mysql> grant all privileges on sbtest.* to 'sbtest'@'localhost' with grant option;
# Query OK, 0 rows affected (0.00 sec) |
Then we tell sysbench to prepare the database for testing.
|
1 2 3 4 5 6 |
[root@shana /]$ sysbench --test=oltp --mysql-table-engine=myisam --oltp-table-size=1000000 --mysql-socket=/tmp/mysql.sock --mysql-user=sbtest prepare
# sysbench 0.4.12: multi-threaded system evaluation benchmark
#
# No DB drivers specified, using mysql
# Creating table 'sbtest'...
# Creating 1000000 records in table 'sbtest'... |
Here we’re creating a table sbtest and populating it with a million records. Then we can run the benchmark:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
[root@shana /]$ sysbench --num-threads=16 --max-requests=100000 --test=oltp --oltp-table-size=1000000 --mysql-socket=/tmp/mysql.sock --mysql-user=sbtest run
# sysbench 0.4.12: multi-threaded system evaluation benchmark
#
# No DB drivers specified, using mysql
# Running the test with following options:
# Number of threads: 16
#
# Doing OLTP test.
# Running mixed OLTP test
# Using Special distribution (12 iterations, 1 pct of values are returned in 75 pct cases)
# Using "LOCK TABLES WRITE" for starting transactions
# Using auto_inc on the id column
# Maximum number of requests for OLTP test is limited to 100000
# Threads started!
# Done.
#
# OLTP test statistics:
# queries performed:
# read: 1400000
# write: 500000
# other: 200000
# total: 2100000
# transactions: 100000 (193.98 per sec.)
# deadlocks: 0 (0.00 per sec.)
# read/write requests: 1900000 (3685.55 per sec.)
# other operations: 200000 (387.95 per sec.)
#
# Test execution summary:
# total time: 515.5274s
# total number of events: 100000
# total time taken by event execution: 8247.0597
# per-request statistics:
# min: 6.97ms
# avg: 82.47ms
# max: 785.73ms
# approx. 95 percentile: 79.73ms
#
# Threads fairness:
# events (avg/stddev): 6250.0000/0.00
# execution time (avg/stddev): 515.4412/0.02 |
All done! Jump into MySQL to drop the sbtest table, then we run sysbench again but this time with –mysql-table-engine=innodb.
|
1 2 |
mysql> drop table sbtest;
# Query OK, 0 rows affected (0.05 sec) |
Then we can destroy the /mydbtmp filesystem and create it again on a different drive ready for the next test.
Results
The results here are interesting, mostly because of how they contradict the advice linked above.
| Volume | Transactions Per Second | |
|---|---|---|
| MyISAM | InnoDB | |
| zroot (Mirrored HDDs) | 193.98 | 884.76 |
| zapps (Mirrored HDDs with ZIL/L2ARC) | 199.11 | 804.81 |
| zflash (Mirrored SSDs) | 199.03 | 1007.80 |
| zroot logs | 196.44 | 764.76 |
| zflash logs | 186.94 | 912.90 |
Graphically:
Conclusion
It seems the simplest way to improve performance with MySQL is to throw everything on to the SSDs. It is noted though that the InnoDB gains much more performance benefit than MyISAM. If you’re stuck with MyISAM tables it might not be worth investing in a SSD.
For now, I’ll create /var/mysql/data on zflash and store my databases there.

