<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Todd Huss &#187; Database</title>
	<atom:link href="http://gabrito.com/post/category/technical/database/feed" rel="self" type="application/rss+xml" />
	<link>http://gabrito.com</link>
	<description>Anecdotes on Technology Leadership, Ruby, Java, Scala, Cloud Computing, Open-Source, SEO, and Design</description>
	<lastBuildDate>Thu, 08 Dec 2011 00:21:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Production MySQL performance tuning</title>
		<link>http://gabrito.com/post/mysql-performance-tuning</link>
		<comments>http://gabrito.com/post/mysql-performance-tuning#comments</comments>
		<pubDate>Fri, 16 Jan 2009 04:22:00 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/?p=235</guid>
		<description><![CDATA[For the past 9 years I&#8217;ve been working almost exclusively with MySQL (with a little PostgreSQL thrown in) and while I don&#8217;t do nearly as much DBA work these days, I still find myself troubleshooting a query or tuning my.cnf. &#8230; <a href="http://gabrito.com/post/mysql-performance-tuning">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.mysql.com"><img src="http://gabrito.com/wp-content/uploads/2009/01/mysql.gif" alt="mysql" title="mysql" width="114" height="68" class="alignleft size-full wp-image-236" /></a> For the past 9 years I&#8217;ve been working almost exclusively with MySQL (with a little PostgreSQL thrown in) and while I don&#8217;t do nearly as much DBA work these days, I still find myself troubleshooting a query or tuning my.cnf. While in general I find MySQL to be a lot more straightforward to work with, it&#8217;s still equally important to tune it for your applications needs.</p>
<p>To that end one of the tools I want to give a shout out to is the <a href="http://www.day32.com/MySQL/">MySQL Performance Tuning Primer Script</a>. You <a href="http://www.day32.com/MySQL/tuning-primer.sh">download and run it</a> against a production system <span id="more-235"></span>(that has preferably been running under normal load for a day or two so that it&#8217;s gathered stats). It&#8217;s a read-only script so you don&#8217;t need to worry about it changing anything but it makes some great recommendations about which tuning parameters may need adjustment. Here&#8217;s a snippet from from a production server:</p>
<p><strong>KEY BUFFER</strong><br />
Current MyISAM index space = 173 M<br />
Current key_buffer_size = 1 G<br />
Key cache miss rate is 1 : 1003<br />
Key buffer fill ratio = 7.00 %<span style="color:red"><br />
Your key_buffer_size seems to be too high.<br />
Perhaps you can use these resources elsewhere</span><br />
&#8230;<br />
&#8230;<br />
&#8230;</p>
<p>It&#8217;s no replacement for a DBA but if you want to get a somewhat sane my.cnf going for your particular application it&#8217;s a great place to start!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/mysql-performance-tuning/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Standalone Migrations: Using Rails migrations in non Rails projects</title>
		<link>http://gabrito.com/post/standalone-migrations-using-rails-migrations-in-non-rails-projects</link>
		<comments>http://gabrito.com/post/standalone-migrations-using-rails-migrations-in-non-rails-projects#comments</comments>
		<pubDate>Tue, 23 Dec 2008 01:15:47 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://gabrito.com/?p=194</guid>
		<description><![CDATA[Update 8/7/2010: Standalone migrations is now a gem (sudo gem install standalone_migrations) so disregard the outdated installation instructions below Update 7/8/2009: With the latest batch of contributed patches standalone migrations now works just like Rails migrations Update 12/26/2008: I switched &#8230; <a href="http://gabrito.com/post/standalone-migrations-using-rails-migrations-in-non-rails-projects">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/thuss/standalone-migrations/tree/master"><img src="http://gabrito.com/wp-content/uploads/2008/12/github.png" alt="Standalone Migrations" title="Standalone Migrations" width="157" height="60" class="alignleft" /></a><strong>Update 8/7/2010</strong>: Standalone migrations is now a gem (sudo gem install standalone_migrations) so disregard the outdated installation instructions below</p>
<p><strong>Update 7/8/2009</strong>: With the latest batch of contributed patches standalone migrations now works just like Rails migrations<br />
<strong>Update 12/26/2008</strong>: I switched standalone migrations to use a Rakefile instead of a Ruby script.</p>
<p>In my work managing websites I end up working in Ruby, Java, and PHP. In everything but Rails managing the schema requires rolling your own solution. As a result I&#8217;ve started using Rails migrations in non-Rails projects to manage the schema. It&#8217;s not much code but I figured others might benefit from it so I created a little Github project called <a target="_blank" href="http://github.com/thuss/standalone-migrations/tree/master">standalone migrations</a>. </p>
<p>It&#8217;s based on Lincoln Stoll&#8217;s blog post titled <a target="_blank" href="http://lstoll.net/2008/04/stand-alone-activerecord-migrations/">Stand-alone ActiveRecord migrations</a> and David Welton&#8217;s blog post titled <a target="_blank" href="http://journal.dedasys.com/2007/01/28/using-migrations-outside-of-rails">Using Migrations Outside of Rails</a>.</p>
<p>Assuming you have Ruby and Gem installed on your machine, here&#8217;s how to use it:</p>
<pre>
gem install -y activerecord rake mysql
wget http://github.com/thuss/standalone-migrations/zipball/master (or fetch it using <a target="_blank" href="http://git.or.cz/">git</a>)
unzip it, and mv to something like my_non_rails_project/db
cd my_non_rails_project/db/ (or wherever you put it)
cp config/database_sample.yml config/database.yml
vi config/database.yml
./new_migration some_user_story
vi migrations/*_some_user_story.rb
rake db:migrate (this applies your newly created migration)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/standalone-migrations-using-rails-migrations-in-non-rails-projects/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Comparing Amazon EC2 with VPS and dedicated hosting</title>
		<link>http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting</link>
		<comments>http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting#comments</comments>
		<pubDate>Fri, 01 Dec 2006 05:01:21 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting</guid>
		<description><![CDATA[I&#8217;ve been reading all the great things about Amazon EC2 (or Elastic Compute Cloud) and lots of pricing comparisons with VPS and dedicated hosting. I finally got an EC2 account and tinkered a bit and there&#8217;s a big difference between &#8230; <a href="http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been reading all the great things about <a href="http://www.amazon.com/gp/browse.html?node=201590011">Amazon EC2 (or Elastic Compute Cloud)</a> and lots of pricing comparisons with <a href="http://www.vpslink.com/vps-hosting/">VPS</a> and <a href="http://www.dreamhost.com/r.cgi?241603/hosting-dedicated.html">dedicated hosting</a>. I finally got an EC2 account and tinkered a bit and there&#8217;s a big difference between EC2 and Virtual Private Server or Dedicated hosting that most of the preliminary write-ups I&#8217;ve seen completely overlook.<br />
<span id="more-163"></span><br />
- With a VPS or Dedicated server you can shutdown, reboot, crash, or have an outage and your data stays on disk.<br />
- With an Amazon EC2 account when you shutdown, reboot, crash, or have an outage any new data that was not in the server image that you originally uploaded is gone!</p>
<p><!--adsense--></p>
<p>This makes it totally inadequate for running a production database server. On the forums people have argued for using replication or clustering solutions while others have advocated streaming redo logs to Amazon&#8217;s S3 service. However, let&#8217;s look at the disaster recovery scenario if all your virtual machines go down (and don&#8217;t think it can&#8217;t happen, racks overload their circuits, generators fail during a power outages, AC&#8217;s can&#8217;t keep up during heat-waves, etc&#8230;):</p>
<p>- With a VPS or dedicated server you startup your servers, do a data integrity check, and you&#8217;re up and running again!<br />
- With EC2 you restart the database server image, then restore the full database backup from the previous night (which you&#8217;ve been backing up to S3), then you rerun all of the redo logs (which you&#8217;ve also been backing up to S3).</p>
<p>The latter scenario isn&#8217;t that bad with a small database but for with a large database it could add hours to your recovery time. I imagine Amazon will eventually add permanent storage to EC2 and if/when that happens you&#8217;d be able to compare Amazon EC2 to a VPS but right now it&#8217;s comparing apples and oranges!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/comparing-amazon-ec2-with-vps-and-dedicated-hosting/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Upgrading to Spring 2.0 and Hibernate 3.2</title>
		<link>http://gabrito.com/post/upgrading-to-spring-20-and-hibernate-32</link>
		<comments>http://gabrito.com/post/upgrading-to-spring-20-and-hibernate-32#comments</comments>
		<pubDate>Fri, 20 Oct 2006 04:48:43 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/upgrading-to-spring-20-and-hibernate-32</guid>
		<description><![CDATA[Tonight I just completed the upgrade from Spring 1.2 and Hibernate 3.1 to Spring 2.0 and Hibernate 3.2 for work. I was expecting a rough upgrade but was pleasantly surprised how easily it went. Our entire unit and integration test &#8230; <a href="http://gabrito.com/post/upgrading-to-spring-20-and-hibernate-32">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Tonight I just completed the upgrade from Spring 1.2 and Hibernate 3.1 to <a href="http://static.springframework.org/spring/docs/2.0.x/reference/new-in-2.html">Spring 2.0</a> and <a href="http://www.hibernate.org/344.html">Hibernate 3.2</a> for <a href="http://www.greatschools.net">work</a>. I was expecting a rough upgrade but was pleasantly surprised how easily it went.<br />
<span id="more-158"></span><br />
Our entire unit and integration test suite which hits Spring and Hibernate pretty good runs in about the same amount of time so there doesn&#8217;t appear to be any significant performance penalty or improvement with the upgrade.</p>
<p><!--adsense--></p>
<p>I had one minor problem and it was that we connect to multiple databases so we have multiple session factories that interact with EhCache. Hibernates org.hibernate.cache.EhCacheProvider now expects one configuration per sesssion factory which I wasn&#8217;t too excited about given we have 51 databases (1 database per state plus Washington DC) and it&#8217;s been working fine for 2 years with one cache provider. The problem caused this exception:</p>
<pre>
 Invocation of init method failed; nested exception is java.lang.NullPointerException
    [java] Caused by: org.springframework.beans.factory.BeanCreationException:
       Error creating bean with name 'surveysSessionFactory' defined in class path resource
          [gs/data/dao/hibernate/applicationContext-hibernate.xml]:
          Invocation of init method failed;
          nested exception is java.lang.NullPointerException
    [java] Caused by: java.lang.NullPointerException
    [java] at net.sf.ehcache.CacheManager.detectAndFixDiskStorePathConflict(CacheManager.java:269)
    ...
</pre>
<p>However, I wasn&#8217;t the only person who had this problem so a quick search turned up that EhCache now offers the net.sf.ehcache.hibernate.SingletonEhCacheProvider and switching the hibernate.cache.provider_class property to this new provider solved the problem and allows us to continue using a single cache provider.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/upgrading-to-spring-20-and-hibernate-32/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SQL statements mysteriously not replicating with MySQL replication</title>
		<link>http://gabrito.com/post/sql-statements-mysteriously-not-replicating-with-mysql-replication</link>
		<comments>http://gabrito.com/post/sql-statements-mysteriously-not-replicating-with-mysql-replication#comments</comments>
		<pubDate>Wed, 13 Sep 2006 19:53:32 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/sql-statements-mysteriously-not-replicating-with-mysql-replication</guid>
		<description><![CDATA[If you&#8217;re using MySQL replication there&#8217;s a feature/bug that you should be aware of. The following SQL statement would not replicate to the slave servers: mysql -uuser -ppass &#62; insert into dbname.tablename values (1, 2, 3, 4); whereas this one &#8230; <a href="http://gabrito.com/post/sql-statements-mysteriously-not-replicating-with-mysql-replication">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re using MySQL replication there&#8217;s a <a href="http://bugs.mysql.com/bug.php?id=20269">feature/bug</a> that you should be aware of. The following SQL statement would not replicate to the slave servers:<br />
<span id="more-155"></span><br />
<strong>mysql -uuser -ppass<br />
&gt; insert into dbname.tablename values (1, 2, 3, 4);</strong></p>
<p>whereas this one would:</p>
<p><strong>mysql -uuser -ppass dbname<br />
&gt; insert into tablename values (1, 2, 3, 4)&#8221;</strong></p>
<p><!--adsense--></p>
<p>so we ended up with inconsistent data between the master and slave servers. Turns out this only happens if you don&#8217;t specify a default database (either on the command line or via a <strong>use dbname</strong> statement) AND you have a binlog-ignore-db statement in your my.cnf such as:</p>
<p><strong>binlog-ignore-db=mysql</strong></p>
<p>The logic for determining whether to replicate an SQL statement can be found <a href="http://dev.mysql.com/doc/refman/5.0/en/binary-log.html">here in the MySQL online manual</a>. Personally I lean more on the side of this being a bug than a feature because the logic for determining what gets written to the binlog being based on the default database is flawed if you can override the database name in an SQL statement. In any case we&#8217;re going to be removing the binlog-ignore-db from our my.cnf files, however, not everyone can do that as easily if you want to have different permissions in mysql.user between master and slave databases.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/sql-statements-mysteriously-not-replicating-with-mysql-replication/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modeling enumerated types in the database</title>
		<link>http://gabrito.com/post/modeling-enumerated-types-in-the-database</link>
		<comments>http://gabrito.com/post/modeling-enumerated-types-in-the-database#comments</comments>
		<pubDate>Tue, 30 May 2006 02:26:52 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/modeling-enumerated-types-in-the-database</guid>
		<description><![CDATA[Let&#8217;s say you have an Employees table and you want a column to track the status of an employee such as ['employed', 'resigned', 'retired', 'terminated', etc...]. You have a couple of options including: Using your database&#8217;s custom enumeration data-type if &#8230; <a href="http://gabrito.com/post/modeling-enumerated-types-in-the-database">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say you have an Employees table and you want a column to track the status of an employee such as ['employed', 'resigned', 'retired', 'terminated', etc...]. You have a couple of options including:</p>
<ol>
<li>Using your database&#8217;s custom enumeration data-type if it has one</li>
<li>Creating an int or char column and let the mapping live in the code</li>
<li>Creating a lookup table</li>
</ol>
<p><span id="more-141"></span>I generally lean towards the lookup table because:</p>
<ol>
<li>It&#8217;s highly portable</li>
<li>It keeps your database self documenting</li>
<li>It works well with any OR mapping layer</li>
<li>It allows you to add new types via an administrative interface or SQL statement without altering the schema</li>
</ol>
<p>The only downside is performance which usually makes caching of enumerated type lookup tables a necessity!</p>
<p><!--adsense--></p>
<p>In Java/Hibernate land I handle the performance issue with a 2nd level cache such as ehCache. When working in Ruby on Rails I&#8217;ve started using the <a href="http://wiki.rubyonrails.org/rails/pages/Acts+As+Enumerated+Plugin">Acts as Enumerated plugin</a> written by <a href="http://www.adamgreenfield.com/articles/2005/09/12/team-member-trevor-squires">Trevor Squires</a>&#8216; which handles the caching for you and is simple and elegant to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/modeling-enumerated-types-in-the-database/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Creating database test fixtures and the rails export fixtures plugin</title>
		<link>http://gabrito.com/post/creating-database-test-fixtures-and-the-rails-export-fixtures-plugin</link>
		<comments>http://gabrito.com/post/creating-database-test-fixtures-and-the-rails-export-fixtures-plugin#comments</comments>
		<pubDate>Wed, 17 May 2006 05:49:15 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/creating-database-test-fixtures-and-the-rails-export-fixtures-plugin</guid>
		<description><![CDATA[Being able to quickly and easily create test fixtures for your database is important yet it&#8217;s not always easy. There are basically 3 approaches I&#8217;ve seen used: 1. Use a MySQL or PostgreSQL dump that gets imported before the tests &#8230; <a href="http://gabrito.com/post/creating-database-test-fixtures-and-the-rails-export-fixtures-plugin">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Being able to quickly and easily create test fixtures for your database is important yet it&#8217;s not always easy. There are basically 3 approaches I&#8217;ve seen used:</p>
<p>1. Use a MySQL or PostgreSQL dump that gets imported before the tests are run. I&#8217;ve never seen this approach used with Oracle, most likely because it&#8217;s such a PITA to export to text (or at least it used to be)<br />
2. Just create the schema before the tests and then populate the test data in code<br />
3. Use a database test fixture tool such as the <a href="http://dbunit.sourceforge.net/">XML based DBUnit for Java</a> or <a href="http://ar.rubyonrails.org/classes/Fixtures.html">Ruby&#8217;s YAML based fixtures</a><br />
<span id="more-136"></span><br />
I have a strong preference for database test fixture tools because they work across databases (often a requirement at ISV&#8217;s) and generally offers tools to easily export fixtures in addition to importing them. However, the ability to export fixtures from your database to a fixture file is sometimes overlooked but it&#8217;s vitally important as populating those fixtures gets really time consuming if you need to type it all in. The most common use case I run into is when I pull rows of data from production into my local database and once I&#8217;m happy with the sample data want to export it into a fixture file.</p>
<p><!--adsense--></p>
<p>At GreatSchools we&#8217;re a Java shop and we use <a href="http://dbunit.sourceforge.net/">DBUnit</a> which does a fantastic job of exporting and importing database test fixtures. Now that I&#8217;m using Ruby on Rails on outside projects though I was starting to burn out having to manually write the fixtures.yml files by hand because Rails doesn&#8217;t offer an export facility out of the box. In this particular case I was parsing NOAA weather forecasts which I do using script/runner via cron to retrieve over HTTP and populate the database with. They can be fairly lengthy and I needed dozens of records for the tests and the thought of having to write the YAML fixtures file had me scared!</p>
<p>Sure enough after a little web searching I found <a href="http://dev.toolbocks.com/repository/file/plugins/export_fixtures/README">Chris McGrath and Nathaniel Brown&#8217;s export fixtures plugin</a> and I&#8217;m a happy camper again!</p>
<p>Here&#8217;s how you install it:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">script/plugin discover<br />
script/plugin install export_fixtures</div></div>
<p>Then to use it I populate the tables in question with sample data and then run:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rake db:fixtures:export_for_tables TABLES=table1,table2</div></div>
<p>It&#8217;s a little shy on giving you feedback but once it completes you&#8217;ll find table1.yml and table2.yml in the test/fixtures directory with all of the data from your tables in it. They also have other options to <a href="http://dev.toolbocks.com/repository/file/plugins/export_fixtures/README">export data from another database such as production or export data selectively based on a query</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/creating-database-test-fixtures-and-the-rails-export-fixtures-plugin/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Moving MySQL tables live with zero downtime</title>
		<link>http://gabrito.com/post/moving-mysql-tables-live-with-zero-downtime</link>
		<comments>http://gabrito.com/post/moving-mysql-tables-live-with-zero-downtime#comments</comments>
		<pubDate>Wed, 10 May 2006 01:23:26 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/moving-mysql-tables-live-with-zero-downtime</guid>
		<description><![CDATA[The biggest challege to moving large amounts of data into production with (almost) zero downtime with MySQL is that the old table will be dropped and the new table locked while you&#8217;re loading the data. If you try that while &#8230; <a href="http://gabrito.com/post/moving-mysql-tables-live-with-zero-downtime">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The biggest challege to moving large amounts of data into production with (almost) zero downtime with MySQL is that the old table will be dropped and the new table locked while you&#8217;re loading the data. If you try that while serving a lot of traffic you&#8217;ll get into trouble as the database connections start stacking up waiting for the lock to free on that table and then you&#8217;ll hit max connections giving most of your users a 500 error.</p>
<p>If you need to move big tables live you basically have 2 options:<span id="more-134"></span></p>
<p>1. Schedule downtime: boo!<br />
2. Import the new data into a table with an alternate name, then drop the old table and rename the new table to the old. The latter part of the operation is extremely quick under MySQL and we do it all the time while serving over a thousand page views a minute with nary a 500 error to show.</p>
<p><!--adsense--></p>
<p>The standard version of mysqldump doesn&#8217;t offer an option to dump a table and import it into the new database under a temporary name and then quickly replace the old table. However, <a href="http://mysqlblog.lenoxway.net/">JDD</a> (GreatSchools former sysadmin extraordinaire who now works for MySQL) <a href="http://lists.mysql.com/internals/9678">submitted a patch a long while back</a> that does exactly this. The patch offers a -R option such that when it writes out the dump file it imports the data into a table with a temporary name and then it does the almost instantaneous operation of dropping the old table and renaming the new table to replace it.</p>
<p>The <a href="http://lists.mysql.com/internals/9678">patch currently only works on MySQL 4.0</a> but we have an in-house version we&#8217;ve ported to MySQL 5.0 (which I can post here once we&#8217;ve determined it&#8217;s stable). Now that we&#8217;re used to being able to move gigabytes of data live during production hours, I can&#8217;t imagine going back to having to regularly work late nights with scheduled downtime just to get new data live!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/moving-mysql-tables-live-with-zero-downtime/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Load balancing across MySQL servers using JDBC</title>
		<link>http://gabrito.com/post/load-balancing-across-mysql-servers-using-jdbc</link>
		<comments>http://gabrito.com/post/load-balancing-across-mysql-servers-using-jdbc#comments</comments>
		<pubDate>Wed, 01 Feb 2006 16:16:34 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/load-balancing-across-mysql-servers-using-jdbc</guid>
		<description><![CDATA[In our production environment at GreatSchools we have 3 production MySQL database servers: 1 read-write master and 2 read-only slaves. In moving our site from Perl to Java we need to load balance read-only connections across the read-only slave servers &#8230; <a href="http://gabrito.com/post/load-balancing-across-mysql-servers-using-jdbc">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In our production environment at <a href="http://www.greatschools.net">GreatSchools</a> we have 3 production MySQL database servers: 1 read-write master and 2 read-only slaves. In moving our site from Perl to Java we need to load balance read-only connections across the read-only slave servers so that our read-write master doesn&#8217;t get overwhelmed under heavy load. As our systems administrators discovered there&#8217;s a solution to <a href="http://dev.mysql.com/doc/refman/5.0/en/cj-replication-connection.html">load balancing read-only connection in the MySQL JDBC driver</a>!</p>
<p>For the JDBC driver you&#8217;ll need to use the</p>
<div class="codecolorer-container text default function" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">com.mysql.jdbc.ReplicationDriver</div></div>
<p>for the connection string, set a property</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">roundRobinLoadBalance</div></div>
<p>to true, and use</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;jdbc:mysql://master,slave1,slave2/dbname</div></div>
<p>as the connection string. Once you have a connection that you&#8217;ll be using for read-only purposes do a</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">conn.setReadOnly(true)</div></div>
<p>and you&#8217;re off and running!</p>
<p>I&#8217;ve also started using this approach in conjunction with Spring/Hibernate and so far it looks like it will work fine. We&#8217;re going to be doing some more extensive testing and load testing of this feature before we put it into production though!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/load-balancing-across-mysql-servers-using-jdbc/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>More powerful database constraints with regular expressions</title>
		<link>http://gabrito.com/post/more-powerful-database-constraints-with-regular-expressions</link>
		<comments>http://gabrito.com/post/more-powerful-database-constraints-with-regular-expressions#comments</comments>
		<pubDate>Thu, 26 Jan 2006 17:01:36 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/more-powerful-database-constraints-with-regular-expressions</guid>
		<description><![CDATA[Is it just me or do you agree that we should be able to easily apply regular expression constraints to a column in a table without writing a stored procedure? For example if I want to guarantee that a varchar &#8230; <a href="http://gabrito.com/post/more-powerful-database-constraints-with-regular-expressions">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Is it just me or do you agree that we should be able to easily apply regular expression constraints to a column in a table without writing a stored procedure? For example if I want to guarantee that a varchar only contains alpha numeric characters with no spaces in most databases I currently have to write a stored procedure and use a trigger to call it on insert and update. Too much work for something that should be so simple!</p>
<p>Postgres is one of the few databases I&#8217;m aware of that currently solves the problem. You can see an example at <a href="http://joseph.randomnetworks.com/">Joseph Scott&#8217;s Blog</a> of <a href="http://joseph.randomnetworks.com/archives/2004/05/24/postgresql-check-constraint-supports-regular-expressions/">using a regex in a check constraint</a>.</p>
<p>Sure, with <a href="http://ar.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html">Active Record in Ruby I can easily do this in code</a> or in <a href="http://www.hibernate.org/hib_docs/annotations/reference/en/html/validator.html">Java using the Hibernate validator</a> but it&#8217;s a different story when you&#8217;ve got a database with multiple legacy applications and data loading systems running against it. In those cases the database if the final line of defense!</p>
<p>This is just a rant but I&#8217;m shocked that this situation hasn&#8217;t markedly improved over the past 10 years!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/more-powerful-database-constraints-with-regular-expressions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

