<?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>Pervasive Code &#187; servers</title>
	<atom:link href="http://www.pervasivecode.com/blog/category/servers/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pervasivecode.com/blog</link>
	<description>Jamie Flournoy's Software Development Blog</description>
	<lastBuildDate>Mon, 26 Jul 2010 05:29:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Karmic on Xen with Bad /etc/fstab = PAIN</title>
		<link>http://www.pervasivecode.com/blog/2010/02/07/karmic-on-xen-with-bad-etcfstab-pain/</link>
		<comments>http://www.pervasivecode.com/blog/2010/02/07/karmic-on-xen-with-bad-etcfstab-pain/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 00:32:20 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=156</guid>
		<description><![CDATA[Argh! I spent about 5 hours yesterday troubleshooting a failed Ubuntu Jaunty -> Karmic (9.04->9.10) upgrade. It worked fine until I rebooted and then failed to boot. Here&#8217;s how I fixed it.

It failed to boot, saying this:

One or more mounts listed in /etc/fstab cannot yet be mounted
/ : waiting for /dev/xvda1
/tmp : waiting for (null)
/swap [...]]]></description>
			<content:encoded><![CDATA[<p>Argh! I spent about 5 hours yesterday troubleshooting a failed Ubuntu Jaunty -> Karmic (9.04->9.10) upgrade. It worked fine until I rebooted and then failed to boot. Here&#8217;s how I fixed it.<br />
<span id="more-156"></span><br />
It failed to boot, saying this:<br />
<code><br />
One or more mounts listed in /etc/fstab cannot yet be mounted<br />
/ : waiting for /dev/xvda1<br />
/tmp : waiting for (null)<br />
/swap : waiting for /dev/xvda9<br />
</code></p>
<p>I tried a lot of stuff and finally solved it. My solution is on the Ubuntu Forum, here: <a href="http://ubuntuforums.org/showpost.php?p=8789500&#038;postcount=37">One or more of the mounts listed in /etc/fstab/ cannot yet be mounted (Karmic)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/02/07/karmic-on-xen-with-bad-etcfstab-pain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu 9.10 (Jaunty Jackalope) upgrade notes</title>
		<link>http://www.pervasivecode.com/blog/2010/02/06/ubuntu-910-jaunty-jackalope-upgrade-notes/</link>
		<comments>http://www.pervasivecode.com/blog/2010/02/06/ubuntu-910-jaunty-jackalope-upgrade-notes/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 04:24:57 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=154</guid>
		<description><![CDATA[Once again Ubuntu Linux proves itself to be easy to upgrade. Going from 9.04 to 9.10 (one release newer, since their numbering is bsaed on dates) was easy, but included the standard sprinkling of manual re-customization that I&#8217;ve come to expect from Debian based systems.

I did the Network Upgrade for Servers.
I had to re-customize these [...]]]></description>
			<content:encoded><![CDATA[<p>Once again Ubuntu Linux proves itself to be easy to upgrade. Going from 9.04 to 9.10 (one release newer, since their numbering is bsaed on dates) was easy, but included the standard sprinkling of manual re-customization that I&#8217;ve come to expect from Debian based systems.<br />
<span id="more-154"></span><br />
I did the <a href="https://help.ubuntu.com/community/KarmicUpgrades#Network%20Upgrade%20for%20Ubuntu%20Servers%20%28Recommended%29">Network Upgrade for Servers</a>.</p>
<p>I had to re-customize these files since I&#8217;m not running with 100% default configuration:</p>
<p>/etc/monit/monit<br />
/etc/monit/monitrc<br />
/etc/dovecot/dovecot.conf<br />
/etc/apache2/apache2.conf<br />
/etc/php/apache2/php.ini</p>
<p>I basically did a manual diff side by side in Emacs and copied my changes over into the new config files. Reboot, no problems. Nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/02/06/ubuntu-910-jaunty-jackalope-upgrade-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fancier Stubbing of GeoKit for Rails unit tests</title>
		<link>http://www.pervasivecode.com/blog/2009/07/23/fancier-stubbing-of-geokit-for-rails-unit-tests/</link>
		<comments>http://www.pervasivecode.com/blog/2009/07/23/fancier-stubbing-of-geokit-for-rails-unit-tests/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 00:00:44 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[process]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=108</guid>
		<description><![CDATA[I&#8217;m working on a Rails app that uses the ym4r_gm plugin, getting Google to do the geocoding for Thentic. I liked the idea of stubbing the web service call, because all those calls to an external service add up to over 20 seconds of test suite run time(!). That&#8217;s almost half of the 50 second [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a Rails app that uses the ym4r_gm plugin, getting Google to do the geocoding for <a href="http://www.thentic.com/">Thentic</a>. I liked the idea of stubbing the web service call, because all those calls to an external service add up to over 20 seconds of test suite run time(!). That&#8217;s almost half of the 50 second run time of my unit tests (and 50 seconds is much too long for a unit test suite).</p>
<p>I found a good starting point at <a href="http://beardendesigns.com/blogs/permalink/55">geokit stubbing for faster tests</a>. I also wanted a way to stub a geocoding failure, and a way to prevent any unit tests from using the real geocoding web service.</p>
<p>Here&#8217;s how I did it.<br />
<span id="more-108"></span><br />
In test/test_helper.rb, add this:</p>
<pre>
class ActiveSupport::TestCase
  def setup
    GeoKit::Geocoders::MultiGeocoder.stubs(:geocode).raises(RuntimeError,
      'Use mock_geocoding_success! or mock_geocoding_failure! in your test')
  end

  def mock_geocoding_success!
    geocode_payload = GeoKit::GeoLoc.new(:lat => 123.456, :lng => 123.456)
    geocode_payload.success = true
    GeoKit::Geocoders::MultiGeocoder.expects(:geocode).returns(geocode_payload)
  end

  def mock_geocoding_failure!
    geocode_payload = GeoKit::GeoLoc.new
    geocode_payload.success = false
    GeoKit::Geocoders::MultiGeocoder.expects(:geocode).returns(geocode_payload)
  end
end
</pre>
<p>What this does is to force you to choose either one of those mock_geocoding methods before you call the geocode method. To me this seems like a good idea since the integration tests that exercise the full application stack should probably be written using Cucumber and Webrat (which is what I&#8217;m using).</p>
<p>You will probably want to merge my one-line setup method into your existing setup code in test_helper, if any. Also note that this uses <a href="http://mocha.rubyforge.org/">Mocha</a> for mocking.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/07/23/fancier-stubbing-of-geokit-for-rails-unit-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu 8.10 and 9.04 (Intrepid Ibex and Jaunty Jackalope) upgrade notes</title>
		<link>http://www.pervasivecode.com/blog/2009/05/30/ubuntu-jaunty-jackalope-upgrade-notes/</link>
		<comments>http://www.pervasivecode.com/blog/2009/05/30/ubuntu-jaunty-jackalope-upgrade-notes/#comments</comments>
		<pubDate>Sat, 30 May 2009 22:54:18 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[xen]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=96</guid>
		<description><![CDATA[I&#8217;m at WordCamp San Francisco today and decided that running a year old version of WordPress (on a year old version of Ubuntu Linux) was undesirable. So, with the confidence that comes from many relatively easy Ubuntu OS upgrades, I charged ahead. For (I think) the second time ever, things went badly. Here&#8217;s what I [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m at <a href="http://2009.sf.wordcamp.org/">WordCamp San Francisco</a> today and decided that running a year old version of WordPress (on a year old version of <a href="http://www.ubuntu.com/">Ubuntu Linux</a>) was undesirable. So, with the confidence that comes from many relatively easy Ubuntu OS upgrades, I charged ahead. For (I think) the second time ever, things went badly. Here&#8217;s what I did and how I fixed it.<br />
<span id="more-96"></span><br />
First, I had to figure out what release of Ubuntu was currently installed:<br />
<code>lsb_release -a</code></p>
<p>I was on &#8220;hardy&#8221;, a.k.a. the <a href="https://wiki.ubuntu.com/HardyHeron/">Hardy Heron</a> release, a.k.a. Ubuntu 8.04 LTS.</p>
<p>I had not bothered to install <a href="https://wiki.ubuntu.com/IntrepidIbex/">Ubuntu 8.10 / &#8220;Intrepid Ibex&#8221;</a> because I didn&#8217;t have a reason to when it was release. I now wanted to upgrade to <a href="https://wiki.ubuntu.com/JauntyJackalope">Ubuntu 9.04 &#8220;Jaunty Jackalope&#8221;</a> which has <a href="http://wordpress.org/">WordPress</a> 2.7.1, the current release (as of today).</p>
<p>The way to upgrade from 8.04 to 9.04 is to upgrade to 8.10 first. So I did that:</p>
<p><a href="https://help.ubuntu.com/community/IntrepidUpgrades#Network%20Upgrade%20for%20Ubuntu%20Servers%20(Recommended)">Intrepid Upgrades: Network Upgrade for Ubuntu Servers</a> worked really well. I had to do a little bit of manual file merging as usual (I still don&#8217;t understand why dpkg can&#8217;t merge changes from the old file into a new file) but that was it. Easy!</p>
<p>When I rebooted the VPS, it kernel panicked: can&#8217;t mount the root filesystem. Oh crap. /dev/xvda1 is missing? Really? I told the VPS to hard reboot and it came up fine. But that&#8217;s a little scary. (I think this is something more related to my VPS hosting provider than Ubuntu, but I haven&#8217;t yet upgraded my laptop VMWare Ubuntu VPS&#8217;s yet so I&#8217;m not sure.)</p>
<p>The second stage didn&#8217;t go so well. I did the same sort of simple upgrade: the Jaunty <a href="http://www.ubuntu.com/getubuntu/upgrading#Network%20Upgrade%20for%20Ubuntu%20Servers%20%28Recommended%29">Network Upgrade for Ubuntu Servers</a> instructions are the same as the ones for Intrepid. Upgrade, edit a couple of config files, reboot. Kernel panic again, same reason, reboot. Should work, right?</p>
<p>It booted, but had no network access. I was able to log in via my VPS hosting provider&#8217;s SSH remote console feature, so I was able to see that /etc/init.d/networking was failing to start. It was the same problem that&#8217;s described in <a href="http://www.fs3.ph/article/ubuntu-904-in-an-openvz-ve">Ubuntu 9.04 in an OpenVZ VE</a>. Adding that one line to <code>/etc/init.d/networking</code> fixed the problem. Reboot, all better.</p>
<p>So if you&#8217;re doing this upgrade on a VPS, make sure you&#8217;ve added that little 1-line hack after you do the Jaunty upgrade and before you reboot.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/05/30/ubuntu-jaunty-jackalope-upgrade-notes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CentOS 5.3 Minimal VPS Install Guide</title>
		<link>http://www.pervasivecode.com/blog/2009/05/30/centos-53-minimal-vps-install-guide/</link>
		<comments>http://www.pervasivecode.com/blog/2009/05/30/centos-53-minimal-vps-install-guide/#comments</comments>
		<pubDate>Sat, 30 May 2009 16:52:14 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Parallels]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[vmware]]></category>
		<category><![CDATA[xen]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=95</guid>
		<description><![CDATA[I just did this yesterday; you can pretty much just follow my CentOS 5.1 Minimal VPS Install Guide.
The differences are:

When you get to the &#8220;More Minimizing&#8221; section, yum -C grouplist will show a package called &#8220;Yum Utilities&#8221; which you probably want to leave installed.
The Deployment_Guide-en-US file is not there so you don&#8217;t need to remove [...]]]></description>
			<content:encoded><![CDATA[<p>I just did this yesterday; you can pretty much just follow my <a href="http://www.pervasivecode.com/blog/2008/03/29/centos-51-minimal-vps-install-guide/">CentOS 5.1 Minimal VPS Install Guide</a>.</p>
<p>The differences are:</p>
<ul>
<li>When you get to the &#8220;More Minimizing&#8221; section, <code>yum -C grouplist</code> will show a package called &#8220;Yum Utilities&#8221; which you probably want to leave installed.</li>
<li>The <code>Deployment_Guide-en-US</code> file is not there so you don&#8217;t need to remove it.</li>
</ul>
<p>That&#8217;s it.</p>
<p>I should also note that downloading a 3.9GB DVD ISO image in order to build a ~700MB installed OS may not be very efficient. I didn&#8217;t bother looking for a network installer but that might be the way to get this done faster.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/05/30/centos-53-minimal-vps-install-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recommended mount options for ext3</title>
		<link>http://www.pervasivecode.com/blog/2008/05/15/recommended-mount-options-for-ext3/</link>
		<comments>http://www.pervasivecode.com/blog/2008/05/15/recommended-mount-options-for-ext3/#comments</comments>
		<pubDate>Fri, 16 May 2008 03:54:30 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/2008/05/15/recommended-mount-options-for-ext3/</guid>
		<description><![CDATA[The details of the various mount options for the ext3 filesystem are fairly well documented, but as with many things in the Unix world, knowledge is far easier to come by than wisdom. That&#8217;s a pithy way of saying that I had to do some digging to find recommendations, as opposed to explanations. So here [...]]]></description>
			<content:encoded><![CDATA[<p>The details of the various mount options for the ext3 filesystem are fairly well documented, but as with many things in the Unix world, knowledge is far easier to come by than wisdom. That&#8217;s a pithy way of saying that I had to do some digging to find recommendations, as opposed to explanations. So here are my recommendations for ext3 users (which encompasses the majority of the Linux-using world, as far as I can tell).<br />
<span id="more-70"></span></p>
<h2>noatime</h2>
<p>First of all, do yourself a favor and disable <code>atime</code> updates, using the <code>noatime</code> mount option. This yields a <i>huge</i> performance boost. </p>
<p>This is done by adding <code>noatime</code> to the appropriate lines in <code>/etc/fstab</code> (do it once for each ext3 filesystem that&#8217;s listed), in the fourth column, which probably says <code>defaults</code> now.</p>
<p>To make this change to a live, running filesystem, remount the drive (adjust this so that the right disk device is specified at the end of the line:</p>
<pre>sudo mount -o noatime,nodiratime,remount,rw /dev/xvda1</pre>
<p>(My understanding is that the <code>noatime</code> implies the <code>nodiratime</code> option, but I decided to add it just in case this was not true.)</p>
<p><code>atime</code> is a relative of the well known file modification and creation timestamps, but it tracks access to file data. That means that if you read one byte from a file, <i>even if it&#8217;s cached in RAM</i>, you&#8217;re actually also triggering a write to the directory entry for that file, so that its <code>atime</code> can be updated. (If you want to slap your forehead now in disbelief, be my guest.) And if you read a ton of little files (which happens <i>rather often</i> in the unix world), that means a ton of writes to update all of their directory entries. You don&#8217;t want that, right?</p>
<p>But do you need it? Almost certainly not. It&#8217;s required by the POSIX standard, and the need for it to be present and turned on is well debated by people more knowledgeable about this in <a href="http://kerneltrap.org/node/14148">this thread</a> from the Linux kernel mailing list. The summary of their argument is that it&#8217;s the kernel&#8217;s job to remain standards compliant, and only the distributor or user has enough information to know that they don&#8217;t care about that part of the standard and can safely disable it. I can understand that point of view.</p>
<p>Well, I did the reading, and you can safely disable it, unless you&#8217;re using mutt. If you&#8217;re using mutt, or if you&#8217;re just nervous about disabling something that somebody somewhere says you might maybe need someday, then disable <code>atime</code> for every filesystem that doesn&#8217;t have your mail spool on it, and use the <code>relatime</code> mode on that drive. (<code>relatime</code> is a clever hack that simulates <code>atime</code> behavior while skipping the disk write in certain cases.)</p>
<h2>Journaling mode</h2>
<p>Ext3 is a <a href="http://en.wikipedia.org/wiki/Journaling_file_system">journaling filesystem</a>, which is generally a good thing. There are <a href="http://www.gentoo.org/doc/en/articles/l-afig-p8.xml#doc_chap4">three modes of operation</a> for ext3&#8217;s journaling functionality, but which to use?</p>
<p>&#8220;It depends&#8221; is not very satisfying, so an easy rule of thumb would be to use <code>data=journal</code> if you really, really want to ensure the durability of your data, and <code>data=ordered</code> if you can tolerate a teeny tiny chance of data corruption.</p>
<p>I measured all three journaling modes by running <code>time sudo rsnapshot hourly</code> on a VPS that backed up VPSs on the same physical server to a dedicated backup disk. In other words, the source was on the same physical server as the destination but they were on different disks.</p>
<p><code>rsnapshot</code> uses hard links to share file data across backup sets, so backing up an unchanged directory twice takes a hardly any additional space compared to backing it up once. But it does need to do a bunch of disk reads and writes to make all the linked directory entries when it does this, so there is a fair amount of I/O involved: more than what rsync would need to just update a local directory to match the remote directory, but far less than what would be needed to make a separate copy of every file for each backup.</p>
<p>In abstract terms, the I/O for this backup process involves a lot of small reads and writes, and a very small number of medium or large writes for changed files. All of these occur as fast as the disk can service them, and the disk is quiet aside from this activity.</p>
<p>Here&#8217;s what I measured (in three test runs per journal type):</p>
<style type="text/css">
table tr td {padding: 6px;}
table tr th {padding: 6px; border: 1px #CCC solid; text-weight: bold;}
</style>
<table>
<tr>
<th>Journal Type</th>
<th>Real Time</th>
</tr>
<tr>
<td>data=journal</td>
<td>2m05s, 2m57s, 2m51s</td>
</tr>
<tr>
<td>data=writeback</td>
<td>2m03s, 1m18s, 1m22s</td>
</tr>
<tr>
<td>data=ordered</td>
<td>2m12s, 1m30s, 1m20s</td>
</tr>
</table>
<p>For this application, <code>data=journal</code> takes twice as long as the others, while <code>data=ordered</code> runs just as fast as <code>data=writeback</code> while providing some additional protection.</p>
<p>So <code>data=writeback</code> is useless in my case, and the fact that <code>data=ordered</code> is the default makes sense. You get almost the same level of data protection as with <code>data=journal</code>, but with the performance of <code>data=writeback</code>. Different I/O patterns will give different results, but I suspect that the pattern I tested with is the most common in real server usage. (Note that in ext3&#8217;s v1 journal format, <code>data=journal</code> was the only journal behavior.)</p>
<p>My inclination is to stick with the default setting, even using <code>data=ordered</code> on database servers, since the database is doing its own higher-level journaling in the form of a transaction log. I&#8217;m basing this recommendation on this detail from the Gentoo article:</p>
<blockquote><p>
<em>When appending data to files, data=ordered mode provides all of the integrity guarantees offered by ext3&#8217;s full data journaling mode. However, if part of a file is being overwritten and the system crashes, it&#8217;s possible that the region being written will contain a combination of original blocks interspersed with updated blocks.</em>
</p></blockquote>
<p>Since a database transaction log is generally appended to rather than overwritten, my understanding is that it will protect against the above scenario in which <code>data=ordered</code> can cause a mix of old and new data. The database&#8217;s data files may have a mix of old and new data, but the transaction log would not show that the transaction have been completed yet, so it would be re-run during recovery and the remaining old data would be removed. I think.</p>
<p>The usage pattern where data that you really care about is overwritten regularly (as opposed to logs, which simply append) is rare in my experience, except in the case of database servers which are covered by their own logs as I just mentioned. So I don&#8217;t know of a particular application type that demands the full data journaling mode.</p>
<p>Anyway, I recommend against <code>data=writeback</code> altogether, unless you don&#8217;t mind some data corruption if there&#8217;s a power failure. The speed gain I measured isn&#8217;t worth the risk, in my opinion.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2008/05/15/recommended-mount-options-for-ext3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Save power and heat: spin down backup drives when idle</title>
		<link>http://www.pervasivecode.com/blog/2008/05/15/save-power-and-heat-spin-down-backup-drives-when-idle/</link>
		<comments>http://www.pervasivecode.com/blog/2008/05/15/save-power-and-heat-spin-down-backup-drives-when-idle/#comments</comments>
		<pubDate>Fri, 16 May 2008 00:48:16 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[raid]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/2008/05/15/save-power-and-heat-spin-down-backup-drives-when-idle/</guid>
		<description><![CDATA[Here&#8217;s a tip for those of you who, like me, back up your data to hard disks instead of tapes. Backing up to the same hard disk doesn&#8217;t protect you much (if the disk failed, you&#8217;d lose the data and the backup at once), so presumably you&#8217;re backing up to a separate physical drive. That [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a tip for those of you who, like me, back up your data to hard disks instead of tapes. Backing up to the same hard disk doesn&#8217;t protect you much (if the disk failed, you&#8217;d lose the data and the backup at once), so presumably you&#8217;re backing up to a separate physical drive. That means that the backup drive need not spin 24/7. Instead, it only needs to spin at backup time.<br />
<span id="more-69"></span><br />
Fortunately most disks can be told to spin down when idle, like laptop drives do. For the main disks of a server this is probably not worth the trouble, but for backup drives it can save you a lot of power and heat. Excessive heat kills hard drives, so this can also prolong the life of your backup drive.</p>
<p>On Linux this is accomplished with hdparm:</p>
<pre>sudo hdparm -S 6 /dev/sda</pre>
<p>The numeric value is on a nonlinear scale, so <code>man hdparm</code> and read about the -S option to make sure you pick the value you intended.</p>
<p>You can check the current status (active or standby) like this:</p>
<pre>sudo hdparm -C /dev/sda</pre>
<p>Gotchas:<br />
External drives aren&#8217;t managed directly by the kernel, so hdparm won&#8217;t work on them. My hardware RAID card won&#8217;t pass through these commands. Linux RAID will not pass these commands through, though you may be able to apply the commands individually to RAID set members (which is what I was able to do).</p>
<p>I don&#8217;t know how to do this on a per-drive basis on Mac OS X (<code>pmset</code> apparently affects every drive on the system), or at all on Windows. If you know feel free to post a comment explaining how it&#8217;s done.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2008/05/15/save-power-and-heat-spin-down-backup-drives-when-idle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Retroactively Minimizing Installed Packages on CentOS 5.1</title>
		<link>http://www.pervasivecode.com/blog/2008/04/14/retroactively-minimizing-installed-packages-on-centos-51/</link>
		<comments>http://www.pervasivecode.com/blog/2008/04/14/retroactively-minimizing-installed-packages-on-centos-51/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 01:16:44 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/2008/04/14/retroactively-minimizing-installed-packages-on-centos-51/</guid>
		<description><![CDATA[In my CentOS 5.1 Minimal VPS Install Guide I describe how to install a very lean set of OS packages when starting from scratch. But what if the VPS is preinstalled for you by a hosting provider? There will be things preinstalled that you don&#8217;t need, which will slow down backups and updates, and waste [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="/blog/2008/03/29/centos-51-minimal-vps-install-guide/">CentOS 5.1 Minimal VPS Install Guide</a> I describe how to install a very lean set of OS packages when starting from scratch. But what if the VPS is preinstalled for you by a hosting provider? There will be things preinstalled that you don&#8217;t need, which will slow down backups and updates, and waste the relatively tiny amount of disk space that VPS plans offer. So here are some instructions to help you identify and remove packages that you don&#8217;t need, when they&#8217;ve already been installed.<br />
<span id="more-68"></span><br />
The first thing you need is a list of minimal packages that your server must have in order to function. This is somewhat subjective, so you may wish to customize it, but <a href="/code/CentOS_5.1_minimal_yum_package_names.txt">here is a roughly minimal list of yum package names for CentOS 5.1</a>. Save that on your CentOS machine as minimal_package_names.txt.</p>
<p>Next, you need a way to compare this list to the list of what you have installed. Here&#8217;s a command line that I used:</p>
<p><code>
<pre>yum list installed | awk 'split($1,a,".") { if (NR>2){ print a[1] } }' \\
> installed_package_names.txt ; diff installed_package_names.txt \\
minimal_package_names.txt  | grep '<' | colrm 1 2
</pre>
<p></code></p>
<p>(The awk command is there to strip out the version number and architecture from the package name.)</p>
<p>Now you can run that command and see a list of package names that are not in your minimal_package_names.txt list. You can switch that grep command so it looks for '>' instead of '<', and see things that you consider minimal which are not currently installed.</p>
<p>Then it's just a matter of "yum install foo" and "yum remove foo". I encourage you to use "yum info foo" to make removal decisions one by one, since someone at the ISP probably took the time to research them and thought you might find them useful. You should probably also remove packages in small groups or one by one, because you might be surprised at the dependencies you find. I was surprised to find that uninstalling postgresql-libs would cause httpd (Apache) to be removed as well.</p>
<p>But if you want to automate it, just tack <code>| xargs yum remove</code> on the end of that command, and it will automatically remove them all at once.</p>
<p>Using this as a starting point, you can change your "minimal" packages list to fit your preferences, or even as a quick and dirty alternative to using Kickstart.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2008/04/14/retroactively-minimizing-installed-packages-on-centos-51/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why mod_rails is great for light-duty Rails apps</title>
		<link>http://www.pervasivecode.com/blog/2008/04/14/why-mod_rails-is-a-really-good-thing-for-light-duty-ruby-on-rails/</link>
		<comments>http://www.pervasivecode.com/blog/2008/04/14/why-mod_rails-is-a-really-good-thing-for-light-duty-ruby-on-rails/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 20:30:25 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/2008/04/14/why-mod_rails-is-a-really-good-thing-for-light-duty-ruby-on-rails/</guid>
		<description><![CDATA[The Ruby on Rails story is usually presented to the new developer as a wonderful break from tradition that makes a developer&#8217;s life so much better than the frameworks of the past. The clattering of skeletons in the closet you&#8217;re hearing? Well, that&#8217;s because it makes the sysadmin&#8217;s life much worse than PHP or Java. [...]]]></description>
			<content:encoded><![CDATA[<p>The Ruby on Rails story is usually presented to the new developer as a wonderful break from tradition that makes a developer&#8217;s life so much better than the frameworks of the past. The clattering of skeletons in the closet you&#8217;re hearing? Well, that&#8217;s because it makes the sysadmin&#8217;s life much worse than PHP or Java. That just improved on Friday, with the release of mod_rails. If you&#8217;re looking for a way to do shared (or low traffic) hosting of Rails applications, this is for you.<br />
<span id="more-67"></span><br />
With Java there&#8217;s this alien environment of CLASSPATHs and WARs and JARs and heap size limits, but once you get it up and running, developers can include libraries in with their application or the lib/ directory of the J2EE server, and the sysadmin doesn&#8217;t have to care. A Java developer is unlikely to ask you to build and install a pile of custom libraries.</p>
<p>With PHP it&#8217;s just another Apache module, but you might need to build a few extra libraries and maybe custom-compile Apache. Once you get it up and running, though, you don&#8217;t even need to restart the server when you deploy new code. It&#8217;s automatically updated.</p>
<p>With Ruby on Rails, it has been far uglier, especially as you go further back. The standard &#8220;Matz Ruby Interpreter&#8221; (MRI) doesn&#8217;t thread well and is quite remarkably slow, and Ruby + Rails in an MRI process use a lot lot lot of memory. So you don&#8217;t really want RoR running inside each Apache process. Folks used to use FastCGI (which should have died over a decade ago, but lingers on like a bad cold) but now use Mongrel, which is conceptually kind of like FastCGI, except that it actually works. Mongrel presents the application via HTTP, which is much easier to understand and integrate with other parts of your architecture (such as a load balancer) than FastCGI.</p>
<p>Whereas in J2EE you&#8217;d run one big honkin&#8217; JVM that used lots of memory to load up your code and data structures, but then ran many threads inside that one process, with the limitations of the MRI (green threads and many, many trips into non thread safe C code that requires the use of a &#8220;giant lock&#8221; that essentially makes it single-threaded), you run one process per thread. That&#8217;s like Apache+PHP or OpenSSH or many other unix programs that fork, right? Well, sort of. The issue is that your Ruby code is not seen by the kernel as something that all those forked processes can share; it sees the parsed Ruby code as data, and when the MRI&#8217;s garbage collector marks all those objects during garbage collection, it seems this data as being recently changed, differently for each forked process. So not only do you need 30-70MB or more per process, but very little of that is shared between processes. Ouch!</p>
<p>A second problem is that these processes take a while to start up and load the code, so it&#8217;s not reasonable to embed the Ruby interpreter in Apache when using Rails; the overhead is just too high. So the Mongrel solution is to pre-launch a bunch of interpreters, and have them just sit there until requests arrive. That&#8217;s pretty inefficient from a memory standpoint, but the latency when a request comes in is quite low since there is no initialization needed.</p>
<p>There have been a few interesting alternatives under development: JRuby is very promising, because it reuses all of the investment in VM development that Sun made over the last 10+ years for Java. At this point the JVM is pretty darn good at running many threads across multiple CPU cores, and at garbage collecting efficiently, among other things. These are key weaknesses of MRI, so running Rails on JRuby seems like a huge benefit. I haven&#8217;t tried it yet but I suspect that this will become one of the 2 or 3 most common ways to run Rails applications in the near future.</p>
<p>Another interesting alternative was <a href="http://izumi.plan99.net/blog/index.php/2007/07/29/making-ruby%E2%80%99s-garbage-collector-copy-on-write-friendly-part-3/">some experimental hacking to MRI&#8217;s garbage collector by Hongli Lai</a>, to store its working data separately from the objects being examined, so that preloaded Ruby code would remain shared by many forked interpreter processes over long periods of time. In other words, this is a potentially major memory use savings for Mongrel cluster users, which would in turn allow the sysadmin to run more Mongrels to service more simultaneous requests, or to bump up the database cache, or to increase the size of the running memcached instance. So, this would indirectly be a performance booster, and Ruby could really use that.</p>
<p>This experimentation apparently became <a href="http://www.rubyenterpriseedition.com/">Ruby Enterprise Edition</a>, which as of this writing is not available yet. But the other development coming from Hongli Lai&#8217;s new company, <a href="http://www.phusion.nl">Phusion</a>, is Passenger, a.k.a. <a href="http://www.modrails.com/">mod_rails</a>.</p>
<p>What&#8217;s interesting about mod_rails for the beginning Rails developer is that it is intended to make Rails hosting easier, particularly for shared hosting enviroments, which have been <a href="http://blog.dreamhost.com/2008/01/07/how-ruby-on-rails-could-be-much-better/">struggling</a> to offer Rails hosting in a uniform and cost-effective fashion. That means that in a short while (weeks?), shared hosting plans for fiddling around with Rails will become much cheaper and more widely available than they are now.</p>
<p>What&#8217;s interesting about mod_rails for the experienced sysadmin is that it mimics the min/max process pooling behavior of Apache, and addresses startup overhead in a clever way. It also serves static images via Apache automatically, eliminating the need for a separate block of mod_rewrite rules that must be crafted carefully so as to avoid conflicts with mod_proxy.</p>
<p>The <a href="http://www.modrails.com/documentation/Architectural%20overview.html">architectural overview</a> is comprehensive and well written, but here&#8217;s a summary: The Spawn Server makes a tree of child processes that preloads Ruby, Rails, and your application code for you, and then that is fork()ed to satisfy incoming requests. So the first request after startup incurs startup overhead (in my case, 5 seconds to load the Redmine login page) but subsequent requests get much better response time (.6s to reload that login page).</p>
<p>That seems like a lot of overhead in terms of big Ruby processes. Here&#8217;s what I measured just now: 97MB free with just Apache running (no spawn server yet). After the first page view, there was 36MB free, and four new processes: the Spawn Server taking a little over 6MB (rsize), the FrameworkSpawner taking 20MB (rsize), the ApplicationSpawner taking 34MB (rsize), and one Rails process taking 34MB (rsize).</p>
<p>The new &#8220;free&#8221; value is 36MB. The Buffers and used Swap values remained constant, with only 48KB of swap used. So that means that all four processes, which would seem to need 94MB to run (34+34+20+6), are actually overlapping enough that they are using only 61MB (97-36). And the ApplicationSpawner eventually terminates, leaving 36MB still free, which makes sense &#8211; it&#8217;s the process that fork()ed the Rails process, so they should ideally be overlapping nearly 100%. I&#8217;m surprised that this is so high; based on the GC experimentation that Hongli Lai did, I would have expected them not to overlap as much.</p>
<p>The idle Rails process exits eventually also, controlled by the <a href="http://www.modrails.com/documentation/Users%20guide.html#_configuring_passenger">RailsPoolIdleTime</a> setting. That saves memory but re-introduces the startup overhead. That leaves the FrameworkSpawner and the SpawnServer running, taking about 25MB of memory (quite close to the 20+6 shown by their rsize values).</p>
<p>Let&#8217;s compare this memory footprint to a Mongrel cluster. In a Mongrel cluster the processes start up and stay running forever, so the users are unlikely to incur much startup overhead at all, since it&#8217;s done long before they visit the application. Some amount of application-specific internal overhead is still an issue, though; that might include gradually filling an initially empty memcached, template compilation and/or caching, etc. As for memory, each Mongrel would need the same 34MB of memory, but there&#8217;s no SpawnServer, FrameworkServer, or ApplicationServer, so the extra 25MB of overhead would not be present with a Mongrel cluster.</p>
<p>That means that for a shared hosting setup where many low-traffic Rails sites may be used, or a multifunction server where serving one or more low-traffic Rails applications is just part of the job, mod_rails is a benefit. When the Rails app isn&#8217;t being used, it will exit and free up that memory for other processes. The starting and stopping of Rails with mod_rails is automatic and demand-based, so the sysadmin can tune it and forget about it.</p>
<p>On the other hand, a single dedicated server or VPS with a fixed amount of memory serving a single application would be better off with Mongrel, because of the lower memory overhead (25MB less), and the fact that the Mongrel processes start up before users need them and stay running indefinitely. Mongrel clusters could still potentially benefit from the Ruby Enterprise Edition&#8217;s garbage collector tweak if forking were used after preloading all of the code.</p>
<p>A single-purpose dedicated server running mod_rails could attain similar performance to a Mongrel cluster by simply setting the RailsPoolIdleTime value to a very high number. Then the Rails processes would hang around, and although you&#8217;d pay the price of a 25MB memory overhead, the startup overhead would only be paid by the very first visitor. However, you&#8217;d lose the main benefit of mod_rails, which is demand-based pool resizing, particularly if you&#8217;re running more than one application, Rails version, or Ruby interpreter version.</p>
<p>In short, I think mod_rails is very nice, and having actually used it I&#8217;m impressed with how polished it is for a 1.0 product. But if you&#8217;re already running a single application as a Mongrel cluster on a dedicated server, there&#8217;s no point in switching.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2008/04/14/why-mod_rails-is-a-really-good-thing-for-light-duty-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Sphinx Search init script for Centos 5.1</title>
		<link>http://www.pervasivecode.com/blog/2008/04/14/sphinx-search-init-script-for-centos-51/</link>
		<comments>http://www.pervasivecode.com/blog/2008/04/14/sphinx-search-init-script-for-centos-51/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 06:18:11 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/2008/04/14/sphinx-search-init-script-for-centos-51/</guid>
		<description><![CDATA[Sphinx search is pretty new, and as a result I was unable to find a nice convenient package for it for CentOS 5.1. This is problematic since there is no init script included with the source tarball, and the issue of updating the index is the sysadmin and developer&#8217;s problem, and cannot be configured to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.sphinxsearch.com/">Sphinx search</a> is pretty new, and as a result I was unable to find a nice convenient package for it for CentOS 5.1. This is problematic since there is no init script included with the source tarball, and the issue of updating the index is the sysadmin and developer&#8217;s problem, and cannot be configured to simply update the index when the data changes.<br />
<span id="more-65"></span><br />
The second problem (updates) is one I punted on; for now I have a cron job rebuilding the entire index every 5 minutes, which will probably be replaced with something smarter and lower-latency at a later time.</p>
<p>The first problem (no init script) is easy to solve, but apparently nobody has done so for CentOS 5.1 and published it. So, here is <a href="/code/centos_sphinx_init_script.txt">my CentOS 5.1 init script for the Sphinx Search server</a>. It is known to work with version 0.9.8-rc2.</p>
<p>BTW, the alternative solution to the problem of a daemon not having a System V init script is to just put some extra junk in <code>/etc/rc.local</code>. That is the quick and dirty solution, and is undesirable for several reasons:</p>
<ol>
<li>You can&#8217;t easily stop or restart the service, because it&#8217;s not a service as far as the OS knows; it&#8217;s just some junk in a script that got run a while ago.</li>
<li>You can&#8217;t use <a href="http://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-services-chkconfig.html">chkconfig</a> or its GUI cousin with the creative name, <a href="http://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-services-serviceconf.html">The Services Configuration Tool</a>, to control it and tie it to specific runlevels.</li>
</ol>
<p>(System V runlevels and init scripts are useful, even if you don&#8217;t need all of the runlevel functionality. The stop/start/restart PID stuff is useful by itself.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2008/04/14/sphinx-search-init-script-for-centos-51/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
