Installing Ruby Enterprise Edition on Mac OSX

June 18th, 2009

This is quite trivial and very easy. I wanted to use the same version of ruby on my mac as is running on our production servers (Ruby Enterprise Edition).

Firstly, do a

gem list

and keep this information. You will need to reinstall all your gems once you have successfully installed REE.

Download REE from http://www.rubyenterpriseedition.com/

tar xvfz ruby-enterprise-X.X.X
sudo ./ruby-enterprise-X.X.X/installer

I suggest changing the default location to just /opt/ruby-enterprise – as you are unlikely to need to roll back the symbolic links in your development environment.

Once it is installed, then you need to make sure that you use it for all your gems, ruby, rake tasks. To do this we will sym link in all the executables into /usr/bin

Find any previous versions of ruby

whereis ruby

and

which ruby

Cleanup – backup and remove any old versions and the associated ruby, gems, rake, irb, cap, capify, erb so they are not on your path.

Then sym link from /usr/bin to opt/ruby-enterprise/bin with all the executables that you may require….

sudo ln -s -f /opt/ruby-enterprise/bin/ruby /usr/bin/ruby
sudo ln -s -f /opt/ruby-enterprise/bin/cap    /usr/bin/cap
sudo ln -s -f /opt/ruby-enterprise/bin/capify /usr/bin/capify
sudo ln -s -f /opt/ruby-enterprise/bin/erb    /usr/bin/erb
sudo ln -s -f /opt/ruby-enterprise/bin/gem    /usr/bin/gem
sudo ln -s -f /opt/ruby-enterprise/bin/irb    /usr/bin/irb
sudo ln -s -f /opt/ruby-enterprise/bin/rails  /usr/bin/rails
sudo ln -s -f /opt/ruby-enterprise/bin/rake   /usr/bin/rake
sudo ln -s -f /opt/ruby-enterprise/bin/rdoc   /usr/bin/rdoc

Do a gem list to see what ruby-enterprise came bundled with.

Now you will need to install all your gems again – that you noted earlier.

rails legacy database migration

June 4th, 2009

Just migrated a legacy database into a rails compliant database – and wrote this nifty DSL script to help out….

The rake task generates the Hash data for the table creation, data insert and rollback scripts.

Once you run the rake task, paste the output into the migration modify the update table and column names – then run the migration.

Performance issues with sub-queries in MYSQL 5

May 7th, 2009

I just recently spent some time with a client investigating some performance issues with mysql subqueries.

The obviously contrived example below

Depending on data size the query can run very slow. When running two queries and pasting in the actual IDs the query runs extremely fast.

The good news it is looks like it is fixed in version 6.0 - looking forward to it becoming a production release....

Display access keys automatically

April 7th, 2009

I have written a Javascript routine which displays a list of the available access keys at the bottom of the page.

Maintaining a list of access keys used for each individual page was going to be a tiresome exercise. As Javascript can interrogate a page for this information, it seemed a little silly manually creating the same result.

So, I give you access_keys, an unobtrusive Javascript routine that searches for and displays access keys that it finds at the bottom of each webpage. Now available on GitHub with full instructions.

Thanks go to Radio New Zealand for inspiring this effort and then releasing it to the world.

MySQL dual master active passive replication

April 6th, 2009

Dual master active-passive is a good way to go for a highly available database server. I can offer the following tips for a more painless dual master experience:

  1. Make sure all your tables are INNODB – Fixing a broken replication with any MyISAM tables will cause a good deal of pain – or limit you with unnecessary downtime from your production environment.
  2. If possible, replicate from the beginning. Install your DB’s, configure for replication, create replication user acess rights, then restart your mysql instances. All databases and user rights from that point on will be replicated. If you can’t do this then take a snapshot of the ‘active’ master, and create your passive master from the snapshot. See below for obtaining a consistent snapshot.
  3. Use log-slave-updates so that replicated data that is processed in master-master is also sent to any slaves. If you are replicating of either of your masters for backup, then set this on the master that is also replicating out to secondary slaves – or set on both so you have the freedom to change topologies.
  4. Ensure that max_allowed_packet is consistent accross all master slaves. If you don’t you may experience the Slave IO thread simply stopping with no error message, and NULL seconds behind error
  5. Use sync_binlog=1 so that transactions are written out to the bin logs on each write – relying on the O/S to flush the logs is not satisfactory and wont guard you in the event of a lost server or host. Make sure innodb_flush_log_at_trx_commit is set to 1 (the default)
  6. If you are not replicating all your databases, be aware that the inserts into one database that is not replicated to a database that is replicated – INSERT into replicated_db_name.tablename will not replicate the insert. This can be used to your advantage in a dual replication set up if you need to fix replication errors – but i would still suggest the snapshot approach below
  7. Reset slave is not an option – I could not see this as a way to fix a broken slave. You will end up loosing data. Best refer to the snapshot method
  8. Nagios has some great mysql replication event handlers to warn you in advance of a broken replication setup. You will need this in your production environment – or some other method alerting you of a broken replication
  9. If your replication is broken – make sure no database writes can make it to the passive database. If this happens you may be losing data – and at the least be in for a whole lot of hurt when putting it back together.
  10. use show slave statusG. If you have errors, you can attempt to fix but in dual master remember that your changes will be replicated back to the other masters – and may cause conflicting errors. Use the snapshot method
  11. Use the auto_increment_offset and auto_increment_increment to configure your primary key allocation method so odd primary keys are generated on one master, and even keys are generated on the other.
  12. You can use mysql proxy or a IP load balancer to direct your SQL requests to the active master. If/when your server crashes, the passive master will be up to date and pick up to become the new active master – with no down time – yeah!

The Snapshot Script

export options=' --add-drop-database --triggers --routines --single-transaction --master-data=2 -u mysqluser -p '
export datestamp=`date +%d-%m-%Y`
mysqldump $options --databases database1 database2 database3 > snapshot_$datestamp.sql

The master-data=2 option will create the necessary information to point your new slave at the master and get replication running again – and place it commented out in the first few lines of the file. Use head -40 snapshot.sql to see what it is if your SQL file is large.

The single-transaction option will mean the the database snapshot will be consistent from beginning to end (Innodb only!).

You are pretty safe to run this on a live production server.

You will need to snapshot all the databases that you are replicating in the one command or the master log postion will not be consistent – it is global for all databases.

Once you have the snapshot. Issue a stop slave; on the passive master, load in the database, issue the change master command below, then issue a start slave;


CHANGE MASTER TO
MASTER_HOST='masterXXXXX',
MASTER_USER='mysql_repli_user',
MASTER_PASSWORD='xxxxxxxxx',
MASTER_LOG_FILE='mysql-bin.xxxxxxx',
MASTER_LOG_POS=xxxxxxxxx;

False-positive validation warnings

March 6th, 2009

I had been getting some validation warnings when running some of my specs. The W3 validator confirmed that my xHTML was valid.

After some googling of the problem, it turns out there is a difference between how xhtml and html documents are handled. Essentially, you need to tell the parser that the document is xHTML rather than HTML. More details here, here, and here.

The solution is to tell RSpec that the document is XML based. The options given in the links above work for RUnit based tests. Taking a look at the rspec source, it is checking to see if the response is XML based by noting the Content-Type header record. So, here's the solution I used:

Now, when I run my specs, it correctly parses the response as XHTML and passes validation without any warnings.

Wanted: office space in Te Aro

March 3rd, 2009

We’re on the lookout for some office space in Te Aro. Somewhere between 75 and 125 square meters.

Our wish list includes:

  • Character
  • Earthquake safe
  • Showers
  • Cycle parking

Would appreciate a call if you’re aware of anything like this.

Clean restarts with Mongrel

January 22nd, 2009

The default init.d mongrel script lacked a setting which means that if your server lost power/crashed or you had a mongrel crash, the stale PID files remain and the mongrel_cluster_ctl start command will fail.

This simple fix works great.

Thanks Paul!

Javascript speed test results [UPDATED to include Google Chrome]

November 2nd, 2008

Test case: sorting a table containing 750 rows of data. Using the table-kit library.

Browser Time
Internet Explorer 6.0 (using an XP virtual machine) 19 seconds
Internet Explorer 8.0b2 (using an XP virtual machine) 5 seconds
Firefox 3.0 8 seconds
Firefox 3.1b1 pre 8 seconds
Safari 3.1.2 4 seconds
Webkit trunk (31 Aug 2008) 4 seconds
Google Chrome 9 seconds

It’s great to see modern browsers executing Javascript so fast. It will be interesting to see how Safari 4.0 compares, which is due to be released shortly.

test_fixtures plugin for Ruby on Rails

August 13th, 2008

Want to ensure that your test fixtures are valid? Use the test_fixtures plugin to validate each of your fixtures against the validations defined in your model.

It simply adds a TestFixtures unit test class to your ./test/units directory in your project.

More details are available on github

To install, run: