Five Pounds of Flax

Every culture has a burrito.

Using cookies in Ruby on Rails

Wednesday, March 28, 2007posted by Michael Rothwell @ 10:15 PM

The cookies object looks like a hash, but it isn't really.

# this sets a cookie
cookies[:key]="value"

# this does not retrieve a cookie
value = cookies[:key]

# but this does
value = cookies["key"]


MySQL 5 Replication and Rails: schweet!

Saturday, March 17, 2007posted by Michael Rothwell @ 6:01 PM

I just got master-master replication working between my Mac (OS 10.4.8, MySQL 5.0.19) and one of my Linux servers (Fedora Core 4, MySQL 5.0.37).

I created a database on the Mac for rails development, and it was automatically created on the Linux server as well. I did 'rake db:migrate' on the Mac, and the schema was created on the linux side as well. Then I used the Rails console (script/console) to create a record and save it. I started up the console on the Linux server and listed all of the records, and the new one was there. I created a record on the Linux server and looked on the Mac -- both had the same two records.

Sweet!

An important thing in master-master replication is to take measures to prevent key collision. Rails apps depend on each table having an auto-increment field named "id". If you don't change your MySQL servers' auto-increment behavior, you'll get collisions: one server will allocate id #1, then the second server will try to allocate id #1, then -- boom.

Here's a two-node circular replication setup. NodeA is nodeB's slave, and vice-versa.

Node A:

[mysqld]
server-id = 10 #this should be unique across servers

auto_increment_increment = 10 #an increment value >1 is needed. set this according to # of servers

auto_increment_offset = 1 # where to start autoincrement IDs

master-host = 10.2.3.3 #other machine's address>


master-user = repluser #pre-configured 'replication' user on other server


master-password = replpass # pre-configured 'replication' user's password on other server


log-slave-updates #you need this


replicate-same-server-id = 0 # prevent looping


report-host = nodeA # this should be unique across servers


log-bin = mysql-bin #you need this

Node B:

[mysqld]

server-id = 20 #this should be unique across servers


auto_increment_increment = 10 #an increment value >1 is needed. set this according to # of servers


auto_increment_offset = 2 # where to start autoincrement IDs


master-host = 10.2.3.4 #other machine's address>


master-user = repluser #pre-configured 'replication' user on other server


master-password = replpass # pre-configured 'replication' user's password on other server


log-slave-updates #you need this


replicate-same-server-id = 0 # prevent looping


report-host = nodeB # this should be unique across servers


log-bin = mysql-bin #you need this

I've highlighted the differences between the two configurations in blue, bold text. With this setup, nodeA will create auto-increment IDs of the form: 1, 11, 21, etc., while nodeB will create auto-increment IDs of the form: 2, 12, 22, etc. This prevents key collision. Notice further that I will be limited in the number of master nodes I can add to this setup before I begin to suffer from key collisions. Additionally, increasing the increment reduces the number of records you can store in the table. With a signed INT type for the auto-increment columns, you can store 2147483647/auto_increment_increment records.

Replication copies *everything* between the servers (all databases, etc), so it is easier to start with two empty mysql configurations. You can also zero out both servers if they have been used before: delete master.info, the bin and log files, etc. The file "master.info" keeps track of where the replication has progressed, so it's important to delete it to reset replication. Keep in mind that you'll lose *all* of your data when you do this kind of "reset"!


Check your Linux machines for correct DST info

Thursday, March 08, 2007posted by Michael Rothwell @ 2:48 PM

Use the zdump command, like so:
    /usr/sbin/zdump -v /etc/localtime | grep 2007
You should see lines containing "Sun Mar 11". Here's what I get on one of my FC4 servers:

/etc/localtime Sun Mar 11 06:59:59 2007 UTC = Sun Mar 11 01:59:59 2007 EST isdst=0 gmtoff=-18000
/etc/localtime Sun Mar 11 07:00:00 2007 UTC = Sun Mar 11 03:00:00 2007 EDT isdst=1 gmtoff=-14400
/etc/localtime Sun Nov 4 05:59:59 2007 UTC = Sun Nov 4 01:59:59 2007 EDT isdst=1 gmtoff=-14400
/etc/localtime Sun Nov 4 06:00:00 2007 UTC = Sun Nov 4 01:00:00 2007 EST isdst=0 gmtoff=-18000

If you see something other than Mar 11, then you still need to fix your timezone info.



One day I should finish this...

Saturday, March 03, 2007posted by Michael Rothwell @ 2:53 PM

I never finished version 2 of my ReplayTV client for the Mac. It was coming together nicely, until my ReplayTV died and the company that makes it went bankrupt. A friend of mine has a ReplayTV. I fired up the last build of mReplay2 and pointed it as his machine, and it worked.

Does anyone still have a ReplayTV and a Mac?