starting local mysql database

We transitioned from using sqlite on devel laptops (with inherent very low hassle) to having to run mysql everywhere to as our migrations and some of our complex database operations just didn’t work with sqlite3.

Setting up all the database junk in mysql in annoying. Some developers have laptops with other mysql programs running on them too, and some development machines are shared by multiple projects and multiple developers.

It’s much nicer to just run a “local” mysql. This is relatively easy to do with postgresql, but we are locked into mysql due to corporate desire for someone to buy support from.

Building local clusters for mysql is annoying, but not ultimately that hard. We use several shell scripts, but we think that these could be turned into rake tasks easily, and we intend to do that soon.

These scripts were inheirited from a PHP/Postgresql project call “ITERation” (a TBS.gc.ca project).

There is a Makefile in test/cluster/Makefile

SRCDIR=$(shell cd ../..; pwd) ... %.sh: %.sh.in Makefile sed \ -e 's,@SRCDIR@,'${CortlandSRCDIR}',' \ $< >$@ chmod +x $@ dbflush: etc/initdb.sh etc/rundb.sh etc/shutdb.sh -[ -f run/mysqld/mysqld.pid ] && etc/shutdb.sh rm -rf ${SRCDIR}/db/mysql etc/initdb.sh etc/rundb.sh dbinit: etc/initdb.sh etc/initdb.sh dbstart: etc/rundb.sh etc/rundb.sh

The first is test/cluster/etc/initdb.sh.in.

SRCDIR=@SRCDIR@ USER=${USER} RUNDIR=${SRCDIR}/test/cluster/run LOGDIR=${SRCDIR}/test/cluster/log PIDFILE=${RUNDIR}/mysqld/mysqld.pid ROOTPW=therootpw mkdir -p ${RUNDIR}/mysqld mkdir -p ${SRCDIR}/db/mysql mkdir -p ${LOGDIR}/mysql /usr/bin/mysql_install_db --basedir=/usr --datadir=${SRCDIR}/db/mysql --pid-file=${PIDFILE} --skip-external-locking --socket=${RUNDIR}/mysqld/mysqld.sock --log_bin=${LOGDIR}/mysql/mysql-bin.log /usr/sbin/mysqld --basedir=/usr --datadir=${SRCDIR}/db/mysql --pid-file=${RUNDIR}/mysqld/mysqld.pid --skip-external-locking --socket=${RUNDIR}/mysqld/mysqld.sock --port=3307 --log_bin=${LOGDIR}/mysql/mysql-bin.log & sleep 10 /usr/bin/mysqladmin -h 127.0.0.1 --port=3307 -u root password $ROOTPW echo "update user set host='%' where host='localhost';" | mysql -h 127.0.0.1 -u root --password=$ROOTPW mysql ( echo "CREATE DATABASE application_test;" echo "CREATE DATABASE application_development;" echo "CREATE USER application;" echo "SET PASSWORD FOR application = PASSWORD('nonprivpw');" echo "GRANT SELECT,INDEX,INSERT,UPDATE,DELETE,ALTER,CREATE,DROP ON application_test.* TO 'application'@'%';" echo "GRANT SELECT,INDEX,INSERT,UPDATE,DELETE ON application_development.* TO 'application'@'%';" echo "CREATE USER webuser;" echo "SET PASSWORD FOR webuser = PASSWORD('phppw');" echo "FLUSH PRIVILEGES;" ) | mysql --protocol=socket --socket=${RUNDIR}/mysqld/mysqld.sock -u root --password=$ROOTPW mysql /usr/bin/mysqladmin --protocol=socket --socket=${RUNDIR}/mysqld/mysqld.sock -u root --password=$ROOTPW shutdown

And the script which starts things up for normal things:

SRCDIR=@SRCDIR@ USER=${USER} RUNDIR=${SRCDIR}/test/cluster/run LOGDIR=${SRCDIR}/test/cluster/log SOCKET=${RUNDIR}/mysqld/mysqld.sock mkdir -p ${RUNDIR}/mysqld mkdir -p ${SRCDIR}/db/mysql mkdir -p ${LOGDIR}/mysql ln -s ${SOCKET} ${SRCDIR}/../application.sock /usr/sbin/mysqld --basedir=/usr --datadir=${SRCDIR}/db/mysql --pid-file=${RUNDIR}/mysqld/mysqld.pid --skip-external-locking --socket=${SOCKET} --skip-networking --log_bin=${LOGDIR}/mysql/mysql-bin.log &

The symlink is placed in the dir above because in our case, we have multiple RoR applications that want to read from that database. Slowly we are converting them to RESTful/ActiveResource mechanism.

To access the symlink, the database.yml looks like:

development: adapter: mysql database: application_development username: application password: nonprivpw host: localhost socket: <%= RAILS_ROOT %>/test/cluster/run/mysqld/mysqld.sock