Thursday, December 15, 2011

Ubuntu, MySQL, Slow Rspec tests

I couldn't for the life of me figure out why my 200 simple rspec tests were running so painfully slow on my Ubuntu partition and so quickly in Debian on VirtualBox running in a Windows 7 Host. Apparently, Ubuntu allows the use of barriers on ext4 partitions by default.

You can learn more about the purpose of barriers here: Deciding when to use Linux file system barriers

To disable barriers, open up your /etc/fstab file in an editor of your liking (as sudo).

Look for the line that describes the partition you are running Ubuntu on. For example:

UUID=f54ae48f-7525-4b18-92bf-dbe5b1fb9be6 / ext4 errors=remount-ro 0 1

Add a barrier=0 option so it now looks like this:

UUID=f54ae48f-7525-4b18-92bf-dbe5b1fb9be6 / ext4 barrier=0,errors=remount-ro 0 1

Restart and run rspec. You should see a noticeable difference.

Friday, November 25, 2011

Diff and Patch Rails Gems

Recently I built a gem for rails called wepay-rails. I cloned a copy of it locally so that I can work on it. Eventually though, I wanted to test it with my rails app and make changes to the gem code. So I then put it in my vendor/gems directory while I developed it. The problem I was running into though was making sure that the changes I was making in my vendor-ed version made it into my cloned version. It was a hassle to remember all the changes and make sure that the code moved across ok. I found the solution to this problem: Diff and Patch.

Here are some steps to create a patch from the vendor-ed gem and apply it to the cloned gem for release:

[adamthedev@localhost ~]$ diff -rc cloned_gem_directory/ updated_vendored_gem_directory/ > patchfile.patch

[adamthedev@localhost ~]$ patch -p0 -i patchfile.patch

That's it! Release the cloned gem!

Friday, October 7, 2011

Rails, MySQL, Octopus - MySQL Replication

We are going to replicate our database to have a single slave for readonly access and a master for our writes. I chose Octopus because it is actively maintained, does sharding (a future project), allows selects to happen on the slave and writes to happen on the master out of the box without me having to touch every single "find" in my code base.

We are going to do this on EC2. Your files might be in different locations than mine are.

Let's start with the MySQL Master:

Edit my.cnf and uncomment:
[mysqld]
...
...
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log

This is where the instructions for replication are written by mysql. We also give this mysql server an id of 1.

On your slave, modify the my.cnf and do this:
[mysqld]
...
...
server-id = 2

Now open a mysql client on your master db and do:
mysql> grant replication slave on *.* to 'replication'@XXX.XXX.XXX.XXX identified by 'my_secret_password'

change the above to use an actual ip address after 'replication'@ and also use a real password.

Restart mysql.

Next, do a read lock
mysql> FLUSH TABLES WITH READ LOCK;

Record the file and position on the master. It should give you output like this. Record the file and position to use later.

mysql> SHOW MASTER STATUS;
+——————+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000001 | 1467771 | | |
+——————+———-+————–+——————+

Export data on master using mysql_dump
mysqldump -uroot -p --all-databases --lock-all-tables > all_databases.sql

mysql> unlock tables;

Restart the slave

More coming soon....