Boost Django running unit testing faster with mysql database loaded into Ramdisk / Memory


Running unit testing in Django using “python manage test ” is not enough. Usually unit-testing takes a lot of time to make it done. FYI, I use Fedora 17 and MySQL for my development and usually, it takes about 2-4 minutes to get testing on single application done. Using SQLite is not good option since I always want to running unit-testing under production database which have MySQL + INNODB. Yes, you can say that InnoDB will make it slower rather MyISAM. But, again, I want to run unit testing on the production database architecture.

After googling, I found that “Load MySQL into RamDisk” will boost performance since it will stored into memory. This is interesting, then i give it a shot! Here we go:

1. Mount ramdisk
We mounting tmpfs with size 1GB into /mnt/ramdisk and set permission to “mysql”.

1
2
3
sudo mkdir -p /mnt/ramdisk
sudo mount -t tmpfs -o size=1G tmpfs /mnt/ramdisk
sudo chown mysql:mysql /mnt/ramdisk

2. Copy MySQL
Copy /var/lib/mysql into ramdisk.

1
sudo rsync -avr /var/lib/mysql/* /mnt/ramdisk/

3. Configure MySQL data pointed into ramdisk

First, we need to stop mysqld services by :

1
sudo service mysqld stop

Then, we need to edit “/etc/my.cnf”:

1
2
3
#datadir=/var/lib/mysql
datadir=/mnt/ramdisk/
socket=/var/lib/mysql/mysql.sock

And we’re ready for running MySQL that loaded into Memory:

1
sudo service mysqld start

4. SELINUX Problem
If you got SELINUX problem which block mysqld data access to /mnt/ramdisk, then you need to disable SELINUX or gain permission for MySQL using ramdisk folder for the data storage.

Some tips, you can running unit testing on single application with “python manage.py app”. You also can running unit testing on particular unit-testing method, example:

1
./manage.py test animals.AnimalTestCase.testFluffyAnimals

And we can tuning MySQL in my.cnf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Set the number of open tables for all threads.
table_cache=256
 
# Set the maximum size for internal (in-memory) temporary tables.
tmp_table_size=26M
 
# Set how many threads should be kept in a cache for reuse.
thread_cache_size=8
 
# MyISAM configuration.
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=52M
key_buffer_size=36M
read_rnd_buffer_size=256K
sort_buffer_size=256K
 
# InnoDB configuration.
innodb_data_home_dir=/mnt/ramdisk/
innodb_additional_mem_pool_size=2M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=1M
innodb_buffer_pool_size=25M
innodb_log_file_size=5M
innodb_thread_concurrency=8

There no happiness besides fast django unit-testing 🙂

Some helpful reference to load MySQL into Ram:

http://fedoraforum.org/forum/showthread.php?t=272413
https://raw.github.com/ksolademi/python-dev-utils/master/mysql-ramdisk.py
https://github.com/miracle2k/linuxutils/raw/master/mysqld-ram.sh


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.