I use PHPUnit and the DbUnit extension for my unit tests. Because I use InnoDB tables with foreign keys I cannot use an SQLite database or temporary tables to run my unittests on. So, I have set up a separate MySQL server to run all my unittests on. My PHPUnit bootstrap script simply generates a random database name and imports the schema so that DbUnit can use it.
The only downside is that after a while, you get a bunch of unused databases on the server. So, I have written a simple bash cronjob that deletes all databases from the server that have not been used for 30 days. This script uses the debian-sys-maint MySQL user that is automatically set up on all Debian systems for maintenance tasks.
By default it deletes all databases that have not been changed in 30 days. But, it is trivial to change this. Just edit the TEST variable in the script. If, for example, you want to delete all databases that have not been accessed in 14 days, change the test to "-atime -14" for example. This works als long as you haven't mounted your filesystem using the noatime option.
I installed this script into /etc/cron.weekly.
- #!/bin/bash
- MYSQL="/usr/bin/mysql --defaults-file=/etc/mysql/debian.cnf"
- MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
- # This `find` test is run on a database data directory. If any files are returned,
- # then the database is kept
- TEST="-ctime -30"
- # priority can be overriden and "-s" adds output to stderr
- LOGGER="logger -p cron.notice -t purge-mysql-databases"
- # mysqladmin likes to read /root/.my.cnf. This is usually not what I want
- # as many admins e.g. only store a password without a username there and
- # so break my scripts.
- export HOME=/etc/mysql/
- ## Fetch a particular option from mysql's invocation.
- #
- # Usage: void mysqld_get_param option
- mysqld_get_param() {
- /usr/sbin/mysqld --print-defaults \
- | tr " " "\n" \
- | grep -- "--$1" \
- | tail -n 1 \
- | cut -d= -f2
- }
- #
- # main()
- #
- DATADIR=`mysqld_get_param datadir`
- DATABASES=`$MYSQL -e 'SHOW DATABASES;' | tail -n +2`
- # Loop through all the databases and see which can be deleted
- for DATABASE in $DATABASES; do
- # Do not touch MySQL's own databases
- if [ "$DATABASE" == "mysql" -o $DATABASE == "information_schema" ]; then
- continue
- fi
- FILES=`find $DATADIR/$DATABASE $TEST`
- if [ -z "$FILES" ]; then
- $MYADMIN --force drop $DATABASE > /dev/null
- echo "Dropped inactive database $DATABASE" | $LOGGER
- fi
- done
Comments
#1 Jason
Thanks for taking the time to post this, very useful! I'm hoping to sneak in something slightly off-topic...
You mentioned you use PHPUnit, DBUnit and MySQL. I am just starting out with PHPUnit testing and the SUT is highly database dependent. Have you done any write-ups outlining some of the issues you ran into while setting up PHPUnit/DBUnit with MySQL?
Thanks!
#2 Sander Marechal (http://www.jejik.com)
Hmm.. this might make a nice subject for another article :-)
#3 Giovanni Senile (http://www.giovannisenile.tk)
Just a patch for line 43:
FILES=`find $DATADIR/${DATABASE//-/@002d} $TEST`
So you can manage also database name containing dashes.
So long.
Comments have been retired for this article.