<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Robby on Rails: Tag database</title>
    <link>http://www.robbyonrails.com/articles/tag/database</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>thoughts.sort_by{|t| t[:topic]}.collect </description>
    <item>
      <title>Master/Slave Databases with Ruby on Rails</title>
      <description>&lt;p&gt;Not terribly long ago, I &lt;a href="http://www.robbyonrails.com/articles/2007/10/05/multiple-database-connections-in-ruby-on-rails"&gt;announced Active Delegate&lt;/a&gt;, which was a really lightweight plugin that I developed to allow models to talk to multiple databases for specific methods. The plugin worked great for really simple situations, like individual models.. but when it came time to test with associations it fell apart. I haven&amp;#8217;t had a chance to work on any updates and knew that it was going to take more work to get it going.&lt;/p&gt;


	&lt;p&gt;Earlier this week, we helped one of our bigger clients launch their new web site&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;. For the deployment, we needed to send all writes to a master database and a reads to slaves (initial deployment is talking to almost 10 slaves spread around the globe!). We needed something to get integrated quickly and decided to ditch Active Delegate for the time being and began looking at the following options.&lt;/p&gt;


	&lt;p&gt;I spoke with Rick Olson&lt;sup&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt; and he pointed me to a new plugin that he hasn&amp;#8217;t really released yet. So, I&amp;#8217;m going to do him a favor and announce it for him. Of course&amp;#8230; I got his permission first&amp;#8230; ;-)&lt;/p&gt;


	&lt;h2&gt;Announcing Masochism!&lt;/h2&gt;


	&lt;p&gt;Masochism&lt;sup&gt;&lt;a href="#fn3"&gt;3&lt;/a&gt;&lt;/sup&gt; is a new plugin for Ruby on Rails that allows you to delegate all writes to a master database and reads to a slave database. The configuration process is just a few lines in your environment file and the plugin takes care of the rest.&lt;/p&gt;


	&lt;h3&gt;Installing Masochism&lt;/h3&gt;


	&lt;p&gt;With &lt;a href="http://piston.rubyforge.org/usage.html"&gt;piston&lt;/a&gt;, you can import Masochism with:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  $ cd vendor/plugins
  $ piston import http://ar-code.svn.engineyard.com/plugins/masochism/
&lt;/code&gt;&lt;/pre&gt;

	&lt;ul&gt;
	&lt;li&gt;To learn more about piston, read &lt;a href="http://www.robbyonrails.com/articles/2007/01/16/every-second-counts-with-a-piston-in-your-trunk"&gt;Every Second Counts with a Piston in your trunk&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You can also install it with the old-fashioned way:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  $ ./script/plugin install -x http://ar-code.svn.engineyard.com/plugins/masochism/
&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;Configuring Masochism&lt;/h3&gt;


	&lt;p&gt;The first thing that you&amp;#8217;ll need to do is add another database connection in &lt;code&gt;config/database.yml&lt;/code&gt; for &lt;code&gt;master_database&lt;/code&gt;. By default, Masochism expects you to have a production database, which will be the read-only/slave database. The &lt;code&gt;master_database&lt;/code&gt; will be the connection details for your (you guessed it&amp;#8230;) master database.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# config/database.yml  
production:
  database: masochism_slave_database
  adapter: postgresql
  host: slavedb1.hostname.tld
  ...

master_database:
  database: masochism_master_database
  adapter: postgresql
  host: masterdb.hostname.tld
  ...
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The idea here is that replication will be handled elsewhere and your application can reap the benefits of talking to the slave database for all of it&amp;#8217;s read-only operations and let the master database(s) spend their time writing data.&lt;/p&gt;


	&lt;p&gt;The next step is to set this up in your environment file. In our scenario, this was &lt;code&gt;config/environments/production.rb&lt;/code&gt;.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# Add this to config/environments/production.rb
config.after_initialize do 
  ActiveReload::ConnectionProxy.setup!    
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Voila, you should be good to go now. As I mentioned, we&amp;#8217;ve only been using this for this past week and we&amp;#8217;ve had to address a few problems that the initial version of the plugin didn&amp;#8217;t address. One of our developers, &lt;a href="http://andy.delcambre.com/"&gt;Andy Delcambre&lt;/a&gt;, just posted an article to show how we had a problem with &lt;a href="http://andy.delcambre.com/2007/11/15/masochistic-connection-proxy-with-observers"&gt;using ActiveRecord observers and masochism&lt;/a&gt;, which we&amp;#8217;re sending over a patch for now.&lt;/p&gt;


	&lt;p&gt;As we continue to monitor how this solution works, we&amp;#8217;ll report any findings on our blog. In the meantime, I&amp;#8217;d be interested in knowing what you&amp;#8217;re using to solve this problem. :-)&lt;/p&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;a href="http://contiki.com"&gt;Contiki&lt;/a&gt;, a cool travel company we&amp;#8217;re working with&lt;/p&gt;


	&lt;p id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; Rick just moved to Portland&amp;#8230; welcome to stump town!&lt;/p&gt;


	&lt;p id="fn3"&gt;&lt;sup&gt;3&lt;/sup&gt; &lt;a href="http://ar-code.svn.engineyard.com/plugins/masochism/README"&gt;The Masochism plugin &lt;span class="caps"&gt;README&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
</description>
      <pubDate>Thu, 15 Nov 2007 16:02:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:3420b2e3-a80c-43c9-a136-a58040069607</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2007/11/15/master-slave-databases-with-ruby-on-rails</link>
      <category>Ruby on Rails</category>
      <category>Ruby</category>
      <category>Programming</category>
      <category>PLANET ARGON</category>
      <category>plugins</category>
      <category>masochism</category>
      <category>database</category>
      <category>mysql</category>
      <category>postgresql</category>
      <category>client</category>
      <category>development</category>
      <category>activerecord</category>
      <category>replication</category>
      <category>deployment</category>
    </item>
    <item>
      <title>Fixing PostgreSQL corruption with Rails?</title>
      <description>&lt;p&gt;People have been emailing me to let me know that the search on my blog was broken. Today I finally set out to fix the problem, which looked like a complex issue with my PostgreSQL database. I&amp;#8217;m not sure how long ago it started so I am not sure what was the cause at the moment. If you did a search on my blog you&amp;#8217;d get an application error and behind the scenes, you would see the following error.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;PGError: ERROR:  missing chunk number 0 for toast value 58441&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Eek!&lt;/p&gt;


	&lt;p&gt;So, I tried to &lt;span class="caps"&gt;REINDEX&lt;/span&gt; the table and it didn&amp;#8217;t solve the problem&amp;#8230; so I started poking around with different types of queries to see what I could do to generate the error again. Didn&amp;#8217;t take me long to figure out that it had something to do with the body column in the contents table.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
db_name=# SELECT count(id) FROM contents WHERE body ~* 'postgresql' LIMIT 20;
ERROR:  missing chunk number 0 for toast value 58441

db_name_=# SELECT count(id) FROM contents WHERE excerpt ~* 'postgresql' LIMIT 20;
 count 
-------
     0
(1 row)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;What am I to do? I did some googling (and go figure&amp;#8230; the error being returned was caught on &lt;a href="http://www.google.com/search?&amp;#38;q=missing+chunk+number+0+for+toast+value"&gt;my blog by google&lt;/a&gt;)... which was amusing.&lt;/p&gt;


	&lt;p&gt;In the &lt;code&gt;#postgresql&lt;/code&gt; channel on freenode they recommended that I try and find the specific row in the table that was causing this error. I decided to just run a for loop in &lt;code&gt;script/console&lt;/code&gt; on the Content object in Typo and print out the name of each record until it gave me an error.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
for i in 1..30000
  puts Content.find( i ).title
  i =+ 1
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This began to print out titles of older blog entries and sure enough&amp;#8230; the loop died when it hit the following error. :-)&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  PostgreSQL sequences in Rails
  When TSearch2 Met AJAX
  ActiveRecord::StatementInvalid: PGError: ERROR:  missing chunk number 0 for toast value 58441
  : SELECT * FROM contents WHERE (contents.id = 1678)  LIMIT 1
          from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.1/lib/active_record/connection_adapters/abstract_adapter.rb:88:in `log'
          from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.1/lib/active_record/connection_adapters/postgresql_adapter.rb:137:in `execute'
          from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.1/lib/active_record/connection_adapters/postgresql_adapter.rb:351:in `select'
          from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.1/lib/active_record/connection_adapters/postgresql_adapter.rb:118:in `select_all'
          from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.1/lib/active_record/base.rb:431:in `find_by_sql'
          from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.1/lib/active_record/base.rb:395:in `find'
          from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.1/lib/active_record/base.rb:393:in `find'
          from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.1/lib/active_record/base.rb:409:in `find'
          from (irb):23
          from (irb):22
  &amp;gt;&amp;gt; exit
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;15.seconds.later I logged into psql and ran &lt;code&gt;DELETE FROM contents WHERE id = 1678&lt;/code&gt;... and all is well!&lt;/p&gt;
</description>
      <pubDate>Sat, 05 Aug 2006 19:16:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:378f2847-e095-4a05-931e-94fce37c0914</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2006/08/05/fixing-postgresql-corruption-with-rails</link>
      <category>console</category>
      <category>corruption</category>
      <category>database</category>
    </item>
    <item>
      <title>Rails Migrations and PostgreSQL Constraints</title>
      <description>&lt;p&gt;A question was posed on the Rails mailing list concerning how one would go about adding CONSTRAINTs to the database tables with &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Migration.html"&gt;ActiveRecord::Migration&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;One argument was raised stating that it is easier to handle these in plain &lt;span class="caps"&gt;SQL&lt;/span&gt; schema files. I disagree. :-)&lt;/p&gt;


	&lt;h3&gt;Migrations to the Rescue&lt;/h3&gt;


	&lt;p&gt;Databases evolve and I have recently found the Migration structure to be perfect for handling iterations and schema changes. Using the &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#M000529"&gt;#execute&lt;/a&gt; method has helped move more of my code into the Ruby/Rails framework&amp;#8230; and that just makes things easier to manage in the long-run. This is the approach that we are using at &lt;a href="http://www.planetargon.com/development.html"&gt;&lt;span class="caps"&gt;PLANET ARGON&lt;/span&gt;&lt;/a&gt; with some of our current client projects.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# db/migrate/6_add_foreign_key.rb&lt;/span&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;AddForeignKey&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Migration&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.up&lt;/span&gt;
    &lt;span class="ident"&gt;execute&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ALTER TABLE bees ADD CONSTRAINT beehive_id_fkey FOREIGN KEY
(beehive_id) REFERENCES beehives (id);&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.down&lt;/span&gt;
    &lt;span class="ident"&gt;execute&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ALTER TABLE bees DROP CONSTRAINT beehive_id_fkey;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This gives us an easy way to use the standard, &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M000507"&gt;#create_table&lt;/a&gt; syntax for building our tables with Ruby&amp;#8230; and then we can slap these constraints on later.&lt;/p&gt;


	&lt;p&gt;This would add the constraints&amp;#8230;&lt;/p&gt;


&lt;code&gt;
&lt;pre&gt;
rake migrate VERSION=6
&lt;/pre&gt;
&lt;/code&gt;

...run tests&amp;#8230;
&lt;code&gt;
&lt;pre&gt;
rake
&lt;/pre&gt;
&lt;/code&gt;

...roll back&amp;#8230;
&lt;code&gt;
&lt;pre&gt;
rake migrate VERSION=5
&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;I have found that this approach is really useful with testing in Rails. When I think that I have everything working great (without &lt;span class="caps"&gt;CONSTRAINTS&lt;/span&gt; in PostgreSQL), I run another migration to add a bunch of foreign key and data constraints to the tables and&amp;#8230; run my tests again.&lt;/p&gt;


	&lt;h3&gt;Let&amp;#8217;s give Active Record a Hug&lt;/h3&gt;


	&lt;p&gt;This has helped me &lt;a href="http://www.robbyonrails.com/articles/2005/09/27/the-bitter-sweet-taste-of-agnostic-database-schemas"&gt;gain some trust&lt;/a&gt; in Active Record while still giving me that comforting feeling that &lt;a href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt; is acting as the &lt;em&gt;body guard for my data&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Even if you don&amp;#8217;t end up using Migrations to handle these types of database schema changes, I would highly suggest that you model your implementation after this. I&amp;#8217;ve worked with many database schemas and this just makes it easy to add your new change and run one command to commit it to the database.&lt;/p&gt;


	&lt;p&gt;...and now I go play with beehives&amp;#8230;&lt;/p&gt;
</description>
      <pubDate>Fri, 11 Nov 2005 10:42:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f125682d520f030e69dadb4be8913ebe</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2005/11/11/rails-migrations-and-postgresql-constraints</link>
      <category>Ruby on Rails</category>
      <category>Programming</category>
      <category>rails</category>
      <category>postgresql</category>
      <category>migrations</category>
      <category>database</category>
      <category>activerecord</category>
    </item>
  </channel>
</rss>
