samhuri.net/wayback/@done/sjs Quickly inserting millions of rows with MySQL InnoDB.html

690 lines
37 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>sjs: Quickly inserting millions of rows with MySQL/InnoDB</title>
<link rel="openid.server" href="http://web.archive.org/web/20080929054218/http://www.myopenid.com/server" />
<link rel="openid.delegate" href="http://web.archive.org/web/20080929054218/http://sami-samhuri.myopenid.com/" />
<meta http-equiv="X-XRDS-Location" content="http://sami-samhuri.myopenid.com/xrds" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://web.archive.org/web/20080929054218/http://feeds.feedburner.com/sjs" />
<script src="http://web.archive.org/web/20080929054218js_/http://sami.samhuri.net/javascripts/prototype.js" type="text/javascript"></script>
<link href="http://web.archive.org/web/20080929054218cs_/http://sami.samhuri.net/stylesheets/application.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- BEGIN WAYBACK TOOLBAR INSERT -->
<script type="text/javascript" src="http://staticweb.archive.org/js/disclaim-element.js" ></script>
<script type="text/javascript" src="http://staticweb.archive.org/js/graph-calc.js" ></script>
<script type="text/javascript" src="http://staticweb.archive.org/jflot/jquery.min.js" ></script>
<script type="text/javascript">
//<![CDATA[
var firstDate = 820454400000;
var lastDate = 1325375999999;
var wbPrefix = "http://web.archive.org/web/";
var wbCurrentUrl = "http:\/\/sami.samhuri.net\/2007\/4\/26\/quickly-inserting-millions-of-rows-with-mysql-innodb";
var curYear = -1;
var curMonth = -1;
var yearCount = 16;
var firstYear = 1996;
var imgWidth=400;
var yearImgWidth = 25;
var monthImgWidth = 2;
var trackerVal = "none";
var displayDay = "29";
var displayMonth = "Sep";
var displayYear = "2008";
var prettyMonths = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
function showTrackers(val) {
if(val == trackerVal) {
return;
}
if(val == "inline") {
document.getElementById("displayYearEl").style.color = "#ec008c";
document.getElementById("displayMonthEl").style.color = "#ec008c";
document.getElementById("displayDayEl").style.color = "#ec008c";
} else {
document.getElementById("displayYearEl").innerHTML = displayYear;
document.getElementById("displayYearEl").style.color = "#ff0";
document.getElementById("displayMonthEl").innerHTML = displayMonth;
document.getElementById("displayMonthEl").style.color = "#ff0";
document.getElementById("displayDayEl").innerHTML = displayDay;
document.getElementById("displayDayEl").style.color = "#ff0";
}
document.getElementById("wbMouseTrackYearImg").style.display = val;
document.getElementById("wbMouseTrackMonthImg").style.display = val;
trackerVal = val;
}
function getElementX2(obj) {
var thing = jQuery(obj);
if((thing == undefined)
|| (typeof thing == "undefined")
|| (typeof thing.offset == "undefined")) {
return getElementX(obj);
}
return Math.round(thing.offset().left);
}
function trackMouseMove(event,element) {
var eventX = getEventX(event);
var elementX = getElementX2(element);
var xOff = eventX - elementX;
if(xOff < 0) {
xOff = 0;
} else if(xOff > imgWidth) {
xOff = imgWidth;
}
var monthOff = xOff % yearImgWidth;
var year = Math.floor(xOff / yearImgWidth);
var yearStart = year * yearImgWidth;
var monthOfYear = Math.floor(monthOff / monthImgWidth);
if(monthOfYear > 11) {
monthOfYear = 11;
}
// 1 extra border pixel at the left edge of the year:
var month = (year * 12) + monthOfYear;
var day = 1;
if(monthOff % 2 == 1) {
day = 15;
}
var dateString =
zeroPad(year + firstYear) +
zeroPad(monthOfYear+1,2) +
zeroPad(day,2) + "000000";
var monthString = prettyMonths[monthOfYear];
document.getElementById("displayYearEl").innerHTML = year + 1996;
document.getElementById("displayMonthEl").innerHTML = monthString;
// looks too jarring when it changes..
//document.getElementById("displayDayEl").innerHTML = zeroPad(day,2);
var url = wbPrefix + dateString + '/' + wbCurrentUrl;
document.getElementById('wm-graph-anchor').href = url;
//document.getElementById("wmtbURL").value="evX("+eventX+") elX("+elementX+") xO("+xOff+") y("+year+") m("+month+") monthOff("+monthOff+") DS("+dateString+") Moy("+monthOfYear+") ms("+monthString+")";
if(curYear != year) {
var yrOff = year * yearImgWidth;
document.getElementById("wbMouseTrackYearImg").style.left = yrOff + "px";
curYear = year;
}
if(curMonth != month) {
var mtOff = year + (month * monthImgWidth) + 1;
document.getElementById("wbMouseTrackMonthImg").style.left = mtOff + "px";
curMonth = month;
}
}
//]]>
</script>
<style type="text/css">body{margin-top:0!important;padding-top:0!important;min-width:800px!important;}#wm-ipp a:hover{text-decoration:underline!important;}</style>
<div id="wm-ipp" style="display:none; position:relative;padding:0 5px;min-height:70px;min-width:800px; z-index:9000;">
<div id="wm-ipp-inside" style="position:fixed;padding:0!important;margin:0!important;width:97%;min-width:780px;border:5px solid #000;border-top:none;background-image:url(http://staticweb.archive.org/images/toolbar/wm_tb_bk_trns.png);text-align:center;-moz-box-shadow:1px 1px 3px #333;-webkit-box-shadow:1px 1px 3px #333;box-shadow:1px 1px 3px #333;font-size:11px!important;font-family:'Lucida Grande','Arial',sans-serif!important;">
<table style="border-collapse:collapse;margin:0;padding:0;width:100%;"><tbody><tr>
<td style="padding:10px;vertical-align:top;min-width:110px;">
<a href="http://wayback.archive.org/web/" title="Wayback Machine home page" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wayback-toolbar-logo.png" alt="Wayback Machine" width="110" height="39" border="0"/></a>
</td>
<td style="padding:0!important;text-align:center;vertical-align:top;width:100%;">
<table style="border-collapse:collapse;margin:0 auto;padding:0;width:570px;"><tbody><tr>
<td style="padding:3px 0;" colspan="2">
<form target="_top" method="get" action="http://wayback.archive.org/web/form-submit.jsp" name="wmtb" id="wmtb" style="margin:0!important;padding:0!important;"><input type="text" name="url" id="wmtbURL" value="http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb" style="width:400px;font-size:11px;font-family:'Lucida Grande','Arial',sans-serif;" onfocus="javascript:this.focus();this.select();" /><input type="hidden" name="type" value="replay" /><input type="hidden" name="date" value="20080929054218" /><input type="submit" value="Go" style="font-size:11px;font-family:'Lucida Grande','Arial',sans-serif;margin-left:5px;" /><span id="wm_tb_options" style="display:block;"></span></form>
</td>
<td style="vertical-align:bottom;padding:5px 0 0 0!important;" rowspan="2">
<table style="border-collapse:collapse;width:110px;color:#99a;font-family:'Helvetica','Lucida Grande','Arial',sans-serif;"><tbody>
<!-- NEXT/PREV MONTH NAV AND MONTH INDICATOR -->
<tr style="width:110px;height:16px;font-size:10px!important;">
<td style="padding-right:9px;font-size:11px!important;font-weight:bold;text-transform:uppercase;text-align:right;white-space:nowrap;overflow:visible;" nowrap="nowrap">
<a href="http://web.archive.org/web/20080820114609/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb" style="text-decoration:none;color:#33f;font-weight:bold;background-color:transparent;border:none;" title="20 Aug 2008"><strong>AUG</strong></a>
</td>
<td id="displayMonthEl" style="background:#000;color:#ff0;font-size:11px!important;font-weight:bold;text-transform:uppercase;width:34px;height:15px;padding-top:1px;text-align:center;" title="You are here: 5:42:18 Sep 29, 2008">SEP</td>
<td style="padding-left:9px;font-size:11px!important;font-weight:bold;text-transform:uppercase;white-space:nowrap;overflow:visible;" nowrap="nowrap">
Oct
</td>
</tr>
<!-- NEXT/PREV CAPTURE NAV AND DAY OF MONTH INDICATOR -->
<tr>
<td style="padding-right:9px;white-space:nowrap;overflow:visible;text-align:right!important;vertical-align:middle!important;" nowrap="nowrap">
<a href="http://web.archive.org/web/20080820114609/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb" title="11:46:09 Aug 20, 2008" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wm_tb_prv_on.png" alt="Previous capture" width="14" height="16" border="0" /></a>
</td>
<td id="displayDayEl" style="background:#000;color:#ff0;width:34px;height:24px;padding:2px 0 0 0;text-align:center;font-size:24px;font-weight: bold;" title="You are here: 5:42:18 Sep 29, 2008">29</td>
<td style="padding-left:9px;white-space:nowrap;overflow:visible;text-align:left!important;vertical-align:middle!important;" nowrap="nowrap">
<img src="http://staticweb.archive.org/images/toolbar/wm_tb_nxt_off.png" alt="Next capture" width="14" height="16" border="0"/>
</td>
</tr>
<!-- NEXT/PREV YEAR NAV AND YEAR INDICATOR -->
<tr style="width:110px;height:13px;font-size:9px!important;">
<td style="padding-right:9px;font-size:11px!important;font-weight: bold;text-align:right;white-space:nowrap;overflow:visible;" nowrap="nowrap">
2007
</td>
<td id="displayYearEl" style="background:#000;color:#ff0;font-size:11px!important;font-weight: bold;padding-top:1px;width:34px;height:13px;text-align:center;" title="You are here: 5:42:18 Sep 29, 2008">2008</td>
<td style="padding-left:9px;font-size:11px!important;font-weight: bold;white-space:nowrap;overflow:visible;" nowrap="nowrap">
2009
</td>
</tr>
</tbody></table>
</td>
</tr>
<tr>
<td style="vertical-align:middle;padding:0!important;">
<a href="http://wayback.archive.org/web/20080929054218*/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb" style="color:#33f;font-size:11px;font-weight:bold;background-color:transparent;border:none;" title="See a list of every capture for this URL"><strong>7 captures</strong></a>
<div style="margin:0!important;padding:0!important;color:#666;font-size:9px;padding-top:2px!important;white-space:nowrap;" title="Timespan for captures of this URL">26 Nov 07 - 29 Sep 08</div>
</td>
<td style="padding:0!important;">
<a style="position:relative; white-space:nowrap; width:400px;height:27px;" href="" id="wm-graph-anchor">
<div id="wm-ipp-sparkline" style="position:relative; white-space:nowrap; width:400px;height:27px;background-color:#fff;cursor:pointer;border-right:1px solid #ccc;" title="Explore captures for this URL">
<img id="sparklineImgId" style="position:absolute; z-index:9012; top:0px; left:0px;"
onmouseover="showTrackers('inline');"
onmouseout="showTrackers('none');"
onmousemove="trackMouseMove(event,this)"
alt="sparklines"
width="400"
height="27"
border="0"
src="http://wayback.archive.org/jsp/graph.jsp?graphdata=400_27_1996:-1:000000000000_1997:-1:000000000000_1998:-1:000000000000_1999:-1:000000000000_2000:-1:000000000000_2001:-1:000000000000_2002:-1:000000000000_2003:-1:000000000000_2004:-1:000000000000_2005:-1:000000000000_2006:-1:000000000000_2007:-1:000000000010_2008:8:011101011000_2009:-1:000000000000_2010:-1:000000000000_2011:-1:000000000000"></img>
<img id="wbMouseTrackYearImg"
style="display:none; position:absolute; z-index:9010;"
width="25"
height="27"
border="0"
src="http://staticweb.archive.org/images/toolbar/transp-yellow-pixel.png"></img>
<img id="wbMouseTrackMonthImg"
style="display:none; position:absolute; z-index:9011; "
width="2"
height="27"
border="0"
src="http://staticweb.archive.org/images/toolbar/transp-red-pixel.png"></img>
</div>
</a>
</td>
</tr></tbody></table>
</td>
<td style="text-align:right;padding:5px;width:65px;font-size:11px!important;">
<a href="javascript:;" onclick="document.getElementById('wm-ipp').style.display='none';" style="display:block;padding-right:18px;background:url(http://staticweb.archive.org/images/toolbar/wm_tb_close.png) no-repeat 100% 0;color:#33f;font-family:'Lucida Grande','Arial',sans-serif;margin-bottom:23px;background-color:transparent;border:none;" title="Close the toolbar">Close</a>
<a href="http://faq.web.archive.org/" style="display:block;padding-right:18px;background:url(http://staticweb.archive.org/images/toolbar/wm_tb_help.png) no-repeat 100% 0;color:#33f;font-family:'Lucida Grande','Arial',sans-serif;background-color:transparent;border:none;" title="Get some help using the Wayback Machine">Help</a>
</td>
</tr></tbody></table>
</div>
</div>
<script type="text/javascript">
var wmDisclaimBanner = document.getElementById("wm-ipp");
if(wmDisclaimBanner != null) {
disclaimElement(wmDisclaimBanner);
}
</script>
<!-- END WAYBACK TOOLBAR INSERT -->
<div id="container">
<div id="header">
<h1><span><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/">sjs</a></span></h1>
<h2>geeky ramblings</h2>
</div>
<div id="page">
<div id="content">
<!--
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description
rdf:about=""
trackback:ping=""
dc:title="Quickly inserting millions of rows with MySQL/InnoDB"
dc:identifier="/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb"
dc:description="<p>The absolute first thing you should do is check your MySQL configuration to make sure it&#8217;s sane for the system you&#8217;re using. I kept getting a &#8216;The table is too large&#8217; error on my Gentoo box after inserting several millio..."
dc:creator="sjs"
dc:date="April 26, 2007 14:06" />
</rdf:RDF>
-->
<div class="hentry" id="article-37">
<h2 class="entry-title">
<a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb">Quickly inserting millions of rows with MySQL/InnoDB</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-04-26T14:06:00+00:00">on Thursday, April 26</abbr>
<br class="clear" />
<div class="entry-content">
<p>The absolute first thing you should do is check your MySQL configuration to make sure it&#8217;s sane for the system you&#8217;re using. I kept getting a &#8216;The table is too large&#8217; error on my Gentoo box after inserting several million rows because the default config limits the InnoDB tablespace size to 128M. It was also tuned for a box with as little as 64M of <span class="caps">RAM</span>. That&#8217;s cool for a small <span class="caps">VPS</span> or your old Pentium in the corner collecting dust. For a modern server, workstation, or even notebook with gigs of <span class="caps">RAM</span> you&#8217;ll likely want to make some changes.</p>
<h3>Tweaking my.cnf</h3>
<p>Here are the relevant settings you can tweak in order to work with large datasets efficiently. These are set in your <strong>my.cnf</strong> file, which varies in location.</p>
<p>On Gentoo it resides at <strong>/etc/mysql/my.cnf</strong>.</p>
<p>When MySQL 5.x is installed via DarwinPorts on Mac <span class="caps">OS X</span> you need to copy one of the defaults from <strong>/opt/local/share/mysql5/mysql/</strong> to <strong>/opt/local/etc/mysql5/my.cnf</strong> and then modify it accordingly.</p>
<p>If you use another system you&#8217;re on your own. If you can&#8217;t figure it out, please put down the text editor and leave the poor config file alone! Jokes aside this really is not difficult if you&#8217;re used to configuring *nix programs.</p>
<h3>innodb_buffer_pool_size</h3>
<p>This determines how much memory MySQL uses for table indexes and data. You can set it as low as 8-10M, or high as 50-80% of your memory on a dedicated MySQL server. I have <span class="caps">RAM</span> to burn<sup><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb#fn1">1</a></sup> in my workstation so I set this to 200M, 20% of my 1GB.</p>
<p>[1] I run Fluxbox on Gentoo, I use 200-300M of my 1GB on average and with 200M for MySQL 409M are in use at this moment. Gotta love those lightweight window managers!</p>
<h3>innodb_additional_mem_pool_size</h3>
<p>According to a post<sup><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb#fn1">1</a></sup> on a MySQL mailing list, modern OSs have fast enough mallocs and this variable has little effect on performance. I set mine to 16M before reading that post, so I&#8217;ll just leave it at that.</p>
<p>[1] http://lists.mysql.com/mysql/129247</p>
<h3>innodb_data_file_path</h3>
<p>On Gentoo this one bit me right in the ass, and I mentioned it above. It specifies how large the files used to store your data can be, and how many of them there are. The default setting is almost sane: <tt>ibdata1:10M:autoextend:<b>max:128M</b></tt>. Limiting the total size to 128M caused my test to fail after inserting several million rows.</p>
<p>Simply removing <tt>max:128M</tt> solves the problem. The resulting setting tells the InnoDB engine to use one file, named <b>ibdata1</b> which is initially 10M in size and grows as required.</p>
<h3>innodb_log_file_size</h3>
<p>The default Gentoo config says they (whoever they are) keep this at 25% of <b>innodb_buffer_pool_size</b> so I did just that. 50M in my case.</p>
<h3>innodb_log_buffer_size</h3>
<p>Again I only went as far as the Gentoo config to learn about this setting. They had it at 8M and recommend increasing it if you have large transactions. I can&#8217;t think of any particularly large transactions I currently use but I doubled it to 16M anyway.</p>
<h3>Save my.cnf and restart mysqld</h3>
<p>That&#8217;s it for the MySQL config. Restart mysqld however you do that on your platform. <tt>sudo /etc/init.d/mysql restart</tt> should look familiar to many *nix users.</p>
<p>Now you should be able to insert dozens and indeed hundreds of millions of rows into your InnoDB tables. Sadly this brought little performance gains to the table. MySQL wraps single queries in implicit transactions. Wrapping everything in a transaction may work, but inevitably something will go wrong and you may want the ability to resume inserting the rows instead of starting all over.</p>
<p>The solution now is to execute <tt><span class="caps">SET AUTOCOMMIT</span>=0</tt> before inserting the data, and then issuing a <tt><span class="caps">COMMIT</span></tt> when you&#8217;re done. With all that in place I&#8217;m inserting 14,000,000 rows into both MyISAM and InnoDB tables in 30 minutes. MyISAM is still ~ 2 min faster, but as I said earlier this is adequate for now. Prior to all this it took several <b>hours</b> to insert 14,000,000 rows so I am happy.</p>
<p>Now you can enjoy the speed MyISAM is known for with your InnoDB tables. Consider the data integrity a bonus! ;-)</p>
<div class="extended">
<p><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb">Continue reading...</a></p>
</div>
</div>
<ul class="meta">
<li>
Tags: <a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/linux">linux</a>&nbsp;<a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/mysql">mysql</a>&nbsp;
</li>
<li>
Meta:
<a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb">0 comments</a>,
<a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb">permalink</a>
</li>
</ul>
</div>
<h5><a name="comments">Comments</a></h5>
<p><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb#comment-form">Leave a response</a></p>
<div id="comments_div">
<ol id="comments" class="comments">
</ol>
</div>
<form id="comment-form" method="post" action="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/2007/4/26/quickly-inserting-millions-of-rows-with-mysql-innodb/comments#comment-form">
<fieldset>
<legend>Comment</legend>
<p>
<label class="text" for="comment_author">Name:</label><br/>
<input type="text" id="comment_author" name="comment[author]" value="" />
</p>
<p>
<label class="text" for="comment_author_email">Email Address:</label><br />
<input type="text" id="comment_author_email" name="comment[author_email]" value="" />
</p>
<p>
<label class="text" for="comment_author_url">Website:</label><br />
<input type="text" id="comment_author_url" name="comment[author_url]" value="" />
</p>
<p>
<label class="text" for="comment_body">Comment:</label><br />
<textarea id="comment_body" name="comment[body]"></textarea>
</p>
<div class="formactions">
<input type="submit" value="Post comment" class="submit" />
</div>
</fieldset>
</form>
</div>
<div id="sidebar">
<div class="sidebar-node">
<div id="search" class="search">
<form action="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/search" id="sform" method="get" name="sform">
<p><input type="text" id="q" name="q" value="" /></p>
</form>
</div>
</div>
<div class="sidebar-node">
<h3>Sections</h3>
<ul>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/">geeky ramblings</a> (15)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/emacs">Emacs</a> (3)</li>
</ul>
</div>
<div class="sidebar-node">
<h3>Tags</h3>
<ul>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/activerecord">activerecord</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/alsa">alsa</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/amusement">amusement</a> (6)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/apple">apple</a> (6)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/arc">arc</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/bdd">bdd</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/broken">broken</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/browsers">browsers</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/buffalo">buffalo</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/bundle">bundle</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/cheat">cheat</a> (3)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/coding">coding</a> (22)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/cool">cool</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/coverflow">coverflow</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/crazy">crazy</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/digg">digg</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/drm">drm</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/dtrace">dtrace</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/dubai">dubai</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/elschemo">elschemo</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/emacs">emacs</a> (11)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/english">english</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/extensions">extensions</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/firefox">firefox</a> (3)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/framework">framework</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/funny">funny</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/fuse">fuse</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/games">games</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/gentoo">gentoo</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/german">german</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/gtkpod">gtkpod</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/haskell">haskell</a> (7)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/humans">humans</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/injury">injury</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/inspirado">inspirado</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/iphone">iphone</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/itunes">itunes</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/i_laughed_i_cried">i_laughed_i_cried</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/keyboard">keyboard</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/keyboard%20shortcuts">keyboard shortcuts</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/lemmings">lemmings</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/life">life</a> (13)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/linux">linux</a> (8)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/lisp">lisp</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/lisp%20arc">lisp arc</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/mac%20os%20x">mac os x</a> (6)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/mediawiki">mediawiki</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/mephisto">mephisto</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/migrations">migrations</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/munich">munich</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/mysql">mysql</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/networking">networking</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/opera">opera</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/pedantry">pedantry</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/people">people</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/photo">photo</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/php">php</a> (4)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/programming">programming</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/project%20euler">project euler</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/propaganda">propaganda</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/python">python</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/quickcheck">quickcheck</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/rails">rails</a> (18)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/rails%20on%20rules">rails on rules</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/regex">regex</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/regular%20expressions">regular expressions</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/rest">rest</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/rtfm">rtfm</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/ruby">ruby</a> (14)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/rushcheck">rushcheck</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/sake">sake</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/scheme">scheme</a> (4)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/school">school</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/seaside">seaside</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/secure%20associations">secure associations</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/seekport">seekport</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/snippets">snippets</a> (3)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/ssh">ssh</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/tagify">tagify</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/technology">technology</a> (6)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/test/spec">test/spec</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/textmate">textmate</a> (7)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/tips">tips</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/typo">typo</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/ubuntu">ubuntu</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/usability">usability</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/userscript">userscript</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/vacation">vacation</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/vim">vim</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/volume">volume</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/web">web</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/web%20objects">web objects</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/wikipediafs">wikipediafs</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/windows">windows</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/work">work</a> (1)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/zend">zend</a> (2)</li>
<li><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/tags/zsh">zsh</a> (1)</li>
</ul>
</div>
<div class="sidebar-node">
<h3>Friends &amp; cool blogs</h3>
<ul>
<li><a href="http://web.archive.org/web/20080929054218/http://jim.roepcke.com/">have browser, will travel</a></li>
<li><a href="http://web.archive.org/web/20080929054218/http://cassandrahill.blogspot.com/">cj's chatter</a></li>
</ul>
</div>
<div class="sidebar-node">
<p><a href="http://web.archive.org/web/20080929054218/http://twitter.com/_sjs">
<img src="http://web.archive.org/web/20080929054218im_/http://sami.samhuri.net/assets/2007/6/26/icon_twitter.png" alt="[t]" /> twitter</a></p>
</div>
<div class="sidebar-node">
<p><a href="http://web.archive.org/web/20080929054218/http://mephistoblog.com/" class="powered"><img alt="mephisto-badge-tiny" src="http://web.archive.org/web/20080929054218im_/http://sami.samhuri.net/images/mephisto-badge-tiny.png" /></a></p>
</div>
</div>
<br style="clear:both;" />
</div>
<div id="footer">
<hr />
<p><a href="http://web.archive.org/web/20080929054218/http://sami.samhuri.net/">sjs</a></p>
<ul>
<li>powered by <a href="http://web.archive.org/web/20080929054218/http://mephistoblog.com/">Mephisto</a> /
styled with <a href="http://web.archive.org/web/20080929054218/http://quotedprintable.com/pages/scribbish">scribbish</a></li>
</ul>
</div>
</div>
<script src="http://web.archive.org/web/20080929054218js_/http://www.google-analytics.com/urchin.js" type="text/javascript"> </script>
<script type="text/javascript"> _uacct = "UA-214054-3"; urchinTracker(); </script>
<script src="http://web.archive.org/web/20080929054218js_/http://feeds.feedburner.com/~s/sjs" type="text/javascript" charset="utf-8"></script>
</body>
</html>
<!--
FILE ARCHIVED ON 5:42:18 Sep 29, 2008 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 10:04:24 Dec 11, 2011.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
-->