<?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; MySQL</title>
	<atom:link href="http://gabrito.com/post/category/technical/mysql/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</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>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>MySQL ODBC Driver issues and Excel</title>
		<link>http://gabrito.com/post/mysql-odbc-driver-issues-and-excel</link>
		<comments>http://gabrito.com/post/mysql-odbc-driver-issues-and-excel#comments</comments>
		<pubDate>Tue, 12 Sep 2006 18:59:52 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/mysql-odbc-driver-issues-and-excel</guid>
		<description><![CDATA[Caveat: this post is probably only of interest if you&#8217;re running into this particular MySQL ODBC Driver problem. Hopefully other people running into this issue will find this useful or please add a comment if you find a better way! &#8230; <a href="http://gabrito.com/post/mysql-odbc-driver-issues-and-excel">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Caveat: this post is probably only of interest if you&#8217;re running into this particular MySQL ODBC Driver problem. Hopefully other people running into this issue will find this useful or please add a comment if you find a better way!</p>
<p>Today I had to get an Excel document that was loaded with ODBC database queries that connect to multiple MySQL databases working on a new machine. The problem I ran into is that if there are any MySQL permission issues such as a missing grant, authentication problems, etc&#8230; you&#8217;ll always get the following completely meaningless error message:<br />
<span id="more-154"></span><br />
[MySQL][ODBC 3.51 Driver]Could not find driver {MySQL ODBC 3.51 Driver} in system information. </p>
<p>For the life of me I couldn&#8217;t even figure out how to determine what host/database/user/password a particular query was trying to use in Excel because if you click on <strong>Edit Query</strong> it would tell you it can&#8217;t find the driver. It&#8217;s hard to troubleshoot when you don&#8217;t even know which machine a particular query is trying to connect and it won&#8217;t even show you the SQL for the query if it can&#8217;t connect!</p>
<p><!--adsense--></p>
<p>So to finally figure out what ODBC connections this Excel document was using I scp&#8217;d it over to a Unix machine and used strings:</p>
<p><strong>strings document.xls | grep DRIVER | sort | uniq</strong></p>
<p>which will give you a list something like this:</p>
<pre>
DRIVER={MySQL ODBC 3.51 Driver};DESC=;DATABASE=dbname;SERVER=hostname;UID=user;PASSWORD=password;PORT=0;OPTION=0;STMT=;
DRIVER={MySQL ODBC 3.51 Driver};DESC=;DATABASE=dbname2;SERVER=hostname;UID=user;PASSWORD=password;PORT=0;OPTION=0;STMT=;
DRIVER={MySQL ODBC 3.51 Driver};DESC=;DATABASE=dbname3;SERVER=hostname;UID=user;PASSWORD=password;PORT=0;OPTION=0;STMT=;
</pre>
<p>That allowed me to see all of the database connections the Excel document was using so I could go in and fix the permission issues. If anyone knows an easier way, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/mysql-odbc-driver-issues-and-excel/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Configuring MySQL sql-mode in Ruby on Rails</title>
		<link>http://gabrito.com/post/configuring-mysql-sql-mode-in-ruby-on-rails</link>
		<comments>http://gabrito.com/post/configuring-mysql-sql-mode-in-ruby-on-rails#comments</comments>
		<pubDate>Thu, 08 Jun 2006 03:59:36 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/configuring-mysql-sql-mode-in-ruby-on-rails</guid>
		<description><![CDATA[In my previous post I wrote about setting MySQL to a stricter sql-mode to make it behave like most other databases, however, I recently ran into a case where I couldn&#8217;t set the global sql-mode without breaking some legacy applications. &#8230; <a href="http://gabrito.com/post/configuring-mysql-sql-mode-in-ruby-on-rails">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my previous post I wrote about <a href="http://gabrito.com/post/when-installing-mysql-always-set-the-sql-mode">setting MySQL to a stricter sql-mode to make it behave like most other databases</a>, however, I recently ran into a case where I couldn&#8217;t set the global sql-mode without breaking some legacy applications. I imagine this is also often the case when you host on a shared server where a global configuration change would be out of the question.<br />
<span id="more-144"></span><br />
I realized I needed to set the sql-mode in my Ruby on Rails project so that no matter where it ran it would get consistent behavior (such as <a href="http://gabrito.com/post/mysql-and-not-null-is-not-good">when inserting nulls into non-nullable fields</a>). I did it by reopening the MysqlAdapter class and setting the sql-mode upon connect. To do this add the following to the end of config/environment.rb:</p>
<p><!--adsense--></p>
<pre style="font-size:1.4em">
# Set MySQL to use a strict sql mode for all connections
class ActiveRecord::ConnectionAdapters::MysqlAdapter
  alias :connect_no_sql_mode :connect
  def connect
    connect_no_sql_mode
    execute("SET sql_mode = 'ansi,strict_trans_tables'")
  end
end
</pre>
<p>What really appeals to me about this approach is that the application configures MySQL so that no matter where it runs ( on my servers, on my laptop, on another developers laptop, or on a shared server where you can&#8217;t change the global sql-mode), that MySQL will behave consistently without needing to configure each database installation. You could also use this approach to implement <a href="http://www.justatheory.com/computers/databases/mysql/configuration.html">David Wheeler&#8217;s recommended character set and timezone settings</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/configuring-mysql-sql-mode-in-ruby-on-rails/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When installing MySQL always set the sql-mode</title>
		<link>http://gabrito.com/post/when-installing-mysql-always-set-the-sql-mode</link>
		<comments>http://gabrito.com/post/when-installing-mysql-always-set-the-sql-mode#comments</comments>
		<pubDate>Sun, 28 May 2006 19:51:08 +0000</pubDate>
		<dc:creator>Todd Huss</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Systems Administration]]></category>

		<guid isPermaLink="false">http://gabrito.com/post/when-installing-mysql-always-set-the-sql-mode</guid>
		<description><![CDATA[As I&#8217;ve described before, MySQL has some appalling out of the box settings which will thwart your attempts at good data integrity! They&#8217;ve clearly seen the light though and at least give you an option to achieve good data integrity &#8230; <a href="http://gabrito.com/post/when-installing-mysql-always-set-the-sql-mode">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As <a href="http://gabrito.com/post/mysql-and-not-null-is-not-good">I&#8217;ve described before, MySQL has some appalling out of the box settings</a> which will thwart your attempts at good data integrity! They&#8217;ve clearly seen the light though and at least give you an option to achieve good data integrity through foreign keys in InnoDB and proper handling of non-nullable fields and invalid values through the servers sql-mode setting. </p>
<p>To make matters worse it seems MySQL may have different out of the box settings per platform and per version. For example a friends 5.0.21 install on Windows XP had the sql-mode set with relatively strict settings whereas 5.0.18 on my Mac had an empty sql-mode. This only illustrates the necessity of always explicitly defining these settings with each install yourself so that you get consistent behavior.<br />
<span id="more-140"></span><br />
If you&#8217;re configuring MySQL for a new greenfield project there are 2 things that you should absolutely always do in your my.cnf (or my.ini in Windows):</p>
<p><!--adsense--></p>
<p>1. Use InnoDB for your tables so that foreign keys will work and you&#8217;ll get row level locking instead of MyISAM&#8217;s table level locking: <strong>default-storage-engine=InnoDB</strong><br />
2. Use a <a href="http://mysql.binarycompass.org/doc/refman/5.0/en/server-sql-mode.html">strict SQL mode</a> that insures if you try and insert an invalid value or null into a non-nullabel field that you get an error: <strong>sql-mode=ansi,strict_trans_tables</strong>.</p>
<p>Setting the character set to utf8 and timezone to utc is also a smart thing <a href="http://www.justatheory.com/computers/databases/mysql/configuration.html">as recommended here by David Wheeler</a>.</p>
<p>Where it gets tricky is when you work on multiple projects on your laptop where some legacy code depends on MySQL&#8217;s old settings. I handle this by leaving the sql-mode as ansi/strict and then downgrading when I need to by executing the command <strong>set @@global.sql_mode=&#8221;;</strong> and then when I&#8217;m done going back with <strong>set @@global.sql_mode=&#8217;ansi,strict_trans_tables&#8217;</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrito.com/post/when-installing-mysql-always-set-the-sql-mode/feed</wfw:commentRss>
		<slash:comments>1</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>
	</channel>
</rss>

