Tag Archives: macosx

Running multiple MySQL instances on MacOsX

Recently I had to look at a tool developed in-house to archive data from a main db cluster to an archive cluster. As I had to implement a brand new feature I wanted to test it first on my machine and cover it fully with unit tests, but to do so I obviously needed 2 MySQL instances running on the same machine – one working as a source db and another that I would be archiving the data to.
I’ve already had MySQL installed from a dmg archive (version 5.1.52) running on localhost on port 3306 and as the installed sets it up system-wise I couldn’t just install another one running on a different port. So I looked at one of the MySQL features allowing to run its multiple instances on one machine. And I must say it works really nice and the setup process is really simple.

Set up global symlinks

First of all make sure that the following binaries are in your system PATH.

  • mysql
  • mysqldump
  • my_print_defaults

I have simply simlinked them in /usr/bin directory:

lrwxr-xr-x   1 root    wheel          26 26 Nov 08:17 mysql -> /usr/local/mysql/bin/mysql
lrwxr-xr-x   1 root    wheel          30  9 Mar 11:08 mysqldump -> /usr/local/mysql/bin/mysqldump
lrwxr-xr-x   1 root    wheel          38 18 May 13:12 my_print_defaults -> /usr/local/mysql/bin/my_print_defaults

Setting up separate data directory

The second MySQL instance will store data in a separate data directory so you have to set it up first. Simply use mysql_install_db script to set it up. I have decided to store them  in /usr/local/mysql/data2

sudo /usr/local/mysql/scripts/mysql_install_db --user=_mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data2

MySQL on MacOSx is run by default as _mysql, that’s why I have used –user option when I run the script to set up permissions in a similar way.

Set up multiple instances in my.cnf file

The last thing that I had to do was to configure my instances in my.cnf file which I have placed in /etc folder. Here’s my configuration:

[mysqld_multi]
mysqld     = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
user       = root

[mysqld1]
socket     = /tmp/mysql.sock
port       = 3306
pid-file   = /usr/local/mysql/data/mysqld1.pid
datadir    = /usr/local/mysql/data
language   = /usr/local/mysql/share/english
user       = _mysql

[mysqld2]
socket     = /tmp/mysql.sock2
port       = 3307
pid-file   = /usr/local/mysql/data2/mysqld2.pid
datadir    = /usr/local/mysql/data2
language   = /usr/local/mysql/share/english
user       = _mysql

Every instance is configured in its own section, where you can configure the port you want the instance to be running on and where is the instance data directory.

Managing and accessing multiple instances
To start or stop an instance use mysqld_multi tool and specify the instance number (it matches the number specified in my.cnf file).

sudo /usr/local/mysql/bin/mysqld_multi start 1
sudo /usr/local/mysql/bin/mysqld_multi stop 2

To access mutliple instances you can either connect via IP address:

mysql --host=127.0.0.1 --port=3307 -uroot

or socket

mysql --socket=/tmp/mysql.sock2

For some weird reason to access second instance via IP running locally I had to use address 127.0.0.1 and not localhost name, otherwise the client always connected to the main instance running on port 3306.

Simples!

Resources:

Autotesting with watchr, growl and PHPUnit

Inspired by a conversation at the office couple of days ago with a slightly bald software developer from the UK and @Stubbs I decided to play a bit with the concept of autotesting. I came across it about a year a go during BTDevCon and I really liked it, but back then I have seen it in action, when one of the developers was using it for a demo in Ruby. I haven’t heard about anything similar for PHP so I didn’t dig in further. Until now.

Let’s get back to the concept of autotesting again for a minute.  The other term for it is continuous testing and in short it is about getting an instant feedback on your code while you’re developing it. In practise, the test suite is being triggered every single time you save a file and the results of the run are displayed on the screen. You don’t have to run the test suite manually, it is done for you.

All you need is watchr, growl and growlnotify (which is available as part of Growl Extras). Watchr is a flexible tool that allows you to watch the filesystem and run an arbitrary command when a change is detected, growl is a notification system for Mac OS X and growlnotify is a command-line tool to post Growl notifications.

Watchr

To install watchr you can either install it using gem:

#> sudo gem install watchr
Successfully installed watchr-0.7
1 gem installed
Installing ri documentation for watchr-0.7...
Installing RDoc documentation for watchr-0.7...

or clone the latest version from github, generate the gem and install it from your local disk:

#> git clone git://github.com/mynyml/watchr.git
#> cd watchr
#> gem build watchr.gemspec
   Successfully built RubyGem
   Name: watchr
   Version: 0.7
   File: watchr-0.7.gem
#> sudo gem install watchr-0.7.gem
Successfully installed watchr-0.7
1 gem installed
Installing ri documentation for watchr-0.7...
Installing RDoc documentation for watchr-0.7...

Growl and growlnotify

Growl (with included extras) is available from its home page as a standard dmg image. Just follow onscreen installation instructions.

Setup watchr with PHPUnit

To set up watchr with PHPUnit you only need one configuration file. In there, you define which part of the filesystem you want to watch for changes and what do you want to do when the change occurs. In my case all I want is to execute my test suites. So here is the example file, called watchr.rb and stored in the top level directory of my module:

In the first line, I have set up watchr to watch any file with php extension for incoming changes and when it detects the change to execute code_changed() function. code_changed() does nothing else but executes phpunit command in my Test subdirectory and passes the results to growl() function.  And the growl() function basically parses the results, checks whether tests run successfully or not and executes growlnotify with an appropriate message and image.

Let the fun begin!

All you have to do now is run watchr, start changing your code and watch for growl notifications!

#> watchr watchr.rb
Positive notification

Positive notification

Failure notification

Failure notification

You can get both the configuration and images I have used from my github. Happy continuous testing!

Sources:

git completion on MacOsX

For most of the day I work on a linux machine and I quite got used to having git completion feature for free. But as an occasional MacOsX user I felt quite bad not having the same functionality available. So yesterday I spent a couple of hours googling and playing until I finally got it all working on my MacBook.

Here’s a quick guide.

First of all, you need git-completion script. You can either get it from git source archive

#> curl http://kernel.org/pub/software/scm/git/git-1.7.1.tar.gz -O
#> tar -xzvf git-1.7.1.tar.gz
#> cp git-1.7.1/contrib/completion/git-completion.bash ~/git-completion.bash

or download it directly from github

#> curl http://github.com/git/git/raw/master/contrib/completion/git-completion.bash -O
#> cp git-completion.bash ~/git-completion.bash

Next, modify your ~/.bash_profile file by adding the following line to it:

source ~/git-completion.bash

Now restart you terminal and start using TAB key to autocomplete git commands!

But I didn’t stop there. When I enter a directory with a git repository I like to know which branch it is currently on. To achieve that all you need to do is to modify PS1 environment variable. Add the following line to  your ~/.bash_profile file:

PS1='\u@\h:\W $(__git_ps1 "(%s)")\$ '

Now restart you terminal and cd into a git repository.

sebmarek@proofek:~ $ cd ~/git/phpUnderControl
sebmarek@proofek:phpUnderControl (master)$

To make it even more visible I use bash colouring feature to highlight branch name in a colour of my choice. See bash prompt HOWTO for more details. That’s how my PS1 environment variable looks like:

PS1='\u@\h:\W \[\033[32m\]$(__git_ps1 "(%s)")\[\033[0m\]\$ '

and that’s the result:

sebmarek@proofek:~ $ cd ~/git/phpUnderControl
sebmarek@proofek:phpUnderControl (master)$

Happy giting!