<?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"
	>

<channel>
	<title>Tiger Technologies Blog &#187; Tech Corner</title>
	<atom:link href="http://blog.tigertech.net/category/tech-corner/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tigertech.net</link>
	<description>Behind the scenes at tigertech.net</description>
	<pubDate>Thu, 15 May 2008 05:40:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>WordPress 2.5.1 security update (and mod_security rule)</title>
		<link>http://blog.tigertech.net/posts/wordpress-251-security-update-and-mod_security-rules/</link>
		<comments>http://blog.tigertech.net/posts/wordpress-251-security-update-and-mod_security-rules/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 23:54:19 +0000</pubDate>
		<dc:creator>Robert Mathews</dc:creator>
		
		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[Useful Tips]]></category>

		<category><![CDATA[mod_security]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/?p=115</guid>
		<description><![CDATA[If you use the WordPress 2.5 blog software on your site, be sure to upgrade to WordPress 2.5.1 as soon as possible. The upgrade contains an important security fix. (We&#8217;ve updated our own blog, and it was painless.)
Although all WordPress users should upgrade right away, we&#8217;ve also added a security rule to our servers to [...]]]></description>
			<content:encoded><![CDATA[<p>If you use the WordPress 2.5 blog software on your site, be sure to upgrade to <a href="http://wordpress.org/development/2008/04/wordpress-251/">WordPress 2.5.1</a> as soon as possible. The upgrade contains an important security fix. (We&#8217;ve updated our own blog, and it was painless.)</p>
<p>Although all WordPress users should upgrade right away, we&#8217;ve also added a security rule to our servers to try and protect our customers who haven&#8217;t yet upgraded. Other people may also find the security rule useful if they use <a href="http://www.modsecurity.org/">mod_security</a> on Apache Web servers. The rest of this post contains more technical details.</p>
<p><span id="more-115"></span></p>
<p>So what&#8217;s the <a href="http://seclists.org/fulldisclosure/2008/Apr/0699.html">security problem with WordPress 2.5</a>? Well, if your blog allows strangers to register, the vulnerability allows evildoers to create a new unprivileged username like &#8220;admin0&#8243;, then use the cookie from that username to login as the privileged username &#8220;admin&#8221;.</p>
<p>This works because WordPress creates a login cookie with a value like this for &#8220;admin0&#8243;:</p>
<p><code>admin0|1209331453|2a771ff005c67b2aaa0a872aaa213f39</code></p>
<p>The first part is the username, the second part is the cookie&#8217;s expiration time, and the third part is an MD5 hash of the concatenated username, expiration, and some secret text.</p>
<p>The trouble is that this cookie is also valid:</p>
<p><code>admin|01209331453|2a771ff005c67b2aaa0a872aaa213f39</code></p>
<p>We simply moved the &#8220;0&#8243; from the end of &#8220;admin&#8221; to the beginning of the expiration. Although this changes the username, it doesn&#8217;t change the MD5 hash! That&#8217;s because the text that the hash is based on doesn&#8217;t contain a separator such as a pipe character, as it should. In either case, it&#8217;s just hashing &#8220;admin01209331453&#8243; (plus the same secret text), and the identical hash is valid for both the privileged and unprivileged users. A nasty bug indeed.</p>
<p>You don&#8217;t necessarily need to use &#8220;0&#8243; on the end of the username, either; other digits can be made to work. They increase the expiration time of the cookie, but that doesn&#8217;t make it invalid.</p>
<p>So this vulnerability allows people to create a WordPress username ending in one or more digits, then use the cookie from that username to login as another username without the digits on the end.</p>
<p>Here&#8217;s where mod_security can be useful. It&#8217;s a great defensive tool that we&#8217;ve been using more and more to protect our customers from this kind of attack. If it&#8217;s possible to identify something that&#8217;s different about an &#8220;evil&#8221; page request (compared to a &#8220;good&#8221; page request), you can probably block the evil request using mod_security.</p>
<p>In this case, one thing immediately stands out: a &#8220;good&#8221; request always has a 10 digit expiration time in the cookie, but a &#8220;bad&#8221; request always has 11 or more digits. If we can block WordPress cookies that contain 11 or more digit expirations, that should block the evil request.</p>
<p>This rule for mod_security 1.x does the trick:</p>
<p><code>SecFilterSelective HTTP_Cookie &quot;wordpress_[a-f0-9]{32}=[^\|]+\|[0-9]{11,}\|[a-f0-9]{32}&quot;</code></p>
<p>And here&#8217;s the same rule for mod_security 2.x:</p>
<p><code>SecRule REQUEST_HEADERS:Cookie &quot;wordpress_[a-f0-9]{32}=[^\|]+\|[0-9]{11,}\|[a-f0-9]{32}&quot;</code></p>
<p>This looks for a cookie value containing 11 or more digits between the pipe symbols. This rule successfully blocks a test attack we created, and does not appear to give false positives (we&#8217;ve had it in place on servers that have served several million pages over the last few hours, with no matches beyond our tests).</p>
<p>Just so it&#8217;s clear, our customers don&#8217;t need to use these rules, because they&#8217;re already on all our servers &#8212; but we hope they&#8217;re useful to someone else. </p>
<p>Of course, if you know of any other attack vectors, please post a comment so we can improve the rules.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/wordpress-251-security-update-and-mod_security-rules/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails 2 update coming soon</title>
		<link>http://blog.tigertech.net/posts/rails-2-soon/</link>
		<comments>http://blog.tigertech.net/posts/rails-2-soon/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 18:57:54 +0000</pubDate>
		<dc:creator>Robert Mathews</dc:creator>
		
		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/?p=113</guid>
		<description><![CDATA[A heads-up if you use Ruby on Rails: We&#8217;re going to be upgrading the default version on our servers to 2.0.2 in the next couple of weeks. We want to give you plenty of notice, because when we tried upgrading some older test applications, they didn&#8217;t work without changes.

We&#8217;ll get to the problems below, but [...]]]></description>
			<content:encoded><![CDATA[<p>A heads-up if you use <a href="http://www.rubyonrails.org/">Ruby on Rails</a>: We&#8217;re going to be upgrading the default version on our servers to 2.0.2 in the next couple of weeks. We want to give you plenty of notice, because when we tried upgrading some older test applications, they didn&#8217;t work without changes.</p>
<p><span id="more-113"></span></p>
<p>We&#8217;ll get to the problems below, but first, let&#8217;s consider how Rails versions work. One nice Rails feature is that there can be multiple versions of Rails on the server, and you can choose to &#8220;bind&#8221; your application to a particular Rails version. In fact, <a href="http://support.tigertech.net/ruby#rails-version">new Rails apps are &#8220;bound&#8221; to the default Rails version that&#8217;s on the server</a> when you create the app, which is good for stability. Even when we update Rails, your app continues using the same old version until you change it.</p>
<p>You actually get even more control than that: you can <a href="http://support.tigertech.net/freeze-rails">&#8220;freeze&#8221; your Rails application</a> to any version you like &#8212; even versions newer than the ones on the server. That&#8217;s the main reason we haven&#8217;t been in a  hurry to update to Rails 2 systemwide; you can easily update your Rails app to 2.0.2 now if you want.</p>
<p>So if you&#8217;ve created your own app, and you haven&#8217;t removed the configuration line that binds Rails to a particular server version, nothing we do will affect you. Until you change your Rails version, you&#8217;ll continue using 1.2.6 (or whatever version you&#8217;ve chosen). However, some people may have installed third-party Rails apps that aren&#8217;t bound to a particular version and don&#8217;t have a frozen copy of Rails, and those <strong>would</strong> be affected by an upgrade.</p>
<p>Which brings us to the problems we saw when upgrading some old test applications. After changing the Rails version, they started displaying a &#8220;500 Internal Server Error&#8221; message. The Rails log file shows:</p>
<p><code>Status: 500 Internal Server Error<br />
A secret is required to generate an integrity hash for cookie session data. Use config.action_controller.session = { :session_key => "_myapp_session", :secret => "some secret phrase of at least 30 characters" } in config/environment.rb<br />
</code></p>
<p>Hmmm, all right. So we need to add a line like this to the &#8220;Rails::Initializer.run&#8221; section of the &#8220;config.rb&#8221; file, with some random text like so:</p>
<p><code>config.action_controller.session = { :session_key => "_myapp_session", :secret => "b836b5a8578d3c74a5dbd0956102784f864e7b67" }<br />
</code></p>
<p>That fixed the 500 error. (By the way, if you&#8217;re looking for a good way to generate random strings, try &#8220;head /dev/urandom | sha1sum&#8221; on a <a href="http://support.tigertech.net/shell">command line</a>.)</p>
<p>We then had a couple of other minor issues. The first was that Rails 2 <strong>really</strong> doesn&#8217;t want to work without a valid database. If your Rails app doesn&#8217;t use a database, that&#8217;s apparently &#8220;not a supported configuration&#8221; and you&#8217;ll need to either create a fake database or make some code changes. The second issue was that some things that have been deprecated for some time (such as &#8220;render_text&#8221;) have been completely removed; if you&#8217;ve been putting off making those changes, now&#8217;s the time.</p>
<p>Anyway, if you&#8217;re using Rails, you probably want to test your application for compatibility now. You can do that at any time by <a href="http://support.tigertech.net/freeze-rails">&#8220;freezing&#8221; it to version 2.0.2</a>. If it doesn&#8217;t work, just freeze it back to 1.2.6 while you fix the problems.</p>
<p>(We&#8217;ll post another blog entry when we actually upgrade Rails, of course.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/rails-2-soon/feed/</wfw:commentRss>
		</item>
		<item>
		<title>New &#8220;Backups&#8221; page available in control panel</title>
		<link>http://blog.tigertech.net/posts/new-backup-page-available-in-control-panel/</link>
		<comments>http://blog.tigertech.net/posts/new-backup-page-available-in-control-panel/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 23:48:07 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
		
		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[backups]]></category>

		<category><![CDATA[control panel]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/posts/new-backup-page-available-in-control-panel/</guid>
		<description><![CDATA[As you probably know, we back up all of our servers every night. Our goal is to keep at least seven days of backups available, with additional older backups available where possible.
We&#8217;ve added a new page to our control panel showing the backups available for each account. To see it, just login to the control [...]]]></description>
			<content:encoded><![CDATA[<p>As you probably know, we back up all of our servers every night. Our goal is to keep at least seven days of backups available, with additional older backups available where possible.</p>
<p>We&#8217;ve added a new page to our control panel showing the backups available for each account. To see it, just <a href="http://www.tigertech.net/login.html">login to the control panel</a>, then click <strong>Backups</strong>.</p>
<p>We make backups so that we can recover from unexpected occurrences such as data erasure or server failures. Of course, we also make the backups available to customers, because they can be a real life-saver when you need one. However, we want to remind customers that they should also make their own backups, especially if you need a different backup frequency or retention policy. Our <a href="http://support.tigertech.net/backups">Web page describing our backup system and policies</a> has more details.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/new-backup-page-available-in-control-panel/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL and PHP 5 Security Updates</title>
		<link>http://blog.tigertech.net/posts/mysql-and-php-5-security-updates/</link>
		<comments>http://blog.tigertech.net/posts/mysql-and-php-5-security-updates/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 07:40:23 +0000</pubDate>
		<dc:creator>Robert Mathews</dc:creator>
		
		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[mysql]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[server updates]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/posts/mysql-and-php-5-security-updates/</guid>
		<description><![CDATA[We&#8217;ve installed MySQL and PHP 5 security updates. Customers should not notice any changes; the updates just fix several security issues in PHP 5 and MySQL.
The updates were performed in such a way that new Web server connections were delayed during the 30 seconds or so that PHP and MySQL were unavailable on each server. [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve installed MySQL and PHP 5 <a href="/posts/security-updates/">security updates</a>. Customers should not notice any changes; the updates just fix several security issues in <a href="http://lists.debian.org/debian-security-announce/debian-security-announce-2008/msg00001.html">PHP 5</a> and <a href="http://lists.debian.org/debian-security-announce/debian-security-announce-2008/msg00009.html">MySQL</a>.</p>
<p>The updates were performed in such a way that new Web server connections were delayed during the 30 seconds or so that PHP and MySQL were unavailable on each server. That should mean that as far as scripts on your Web site were concerned, there was zero downtime.</p>
<p><span id="more-100"></span></p>
<p>Since this is &#8220;Tech Corner&#8221;&#8230; If you&#8217;re curious how to do &#8220;zero downtime&#8221; upgrades on Linux, you can use iptables. Something like this works on Debian for MySQL:</p>
<pre>
iptables -I INPUT -p tcp -m multiport --syn --dports 80,443 -j DROP
apt-get install mysql-server-5.0
iptables -D INPUT -p tcp -m multiport --syn --dports 80,443 -j DROP</pre>
<p>The dropping of SYN packets blocks new Web connections (and therefore new MySQL queries) without interrupting existing ones. Since we use DROP instead of REJECT, the client&#8217;s Web browser doesn&#8217;t show an immediate error; it keeps retrying.</p>
<p>The upgrade process then takes about 15 seconds to actually stop MySQL (assuming you&#8217;ve already downloaded the package), which is enough time for existing connections to finish up. It then takes another 15 seconds or so to install the upgrade and restart MySQL.</p>
<p>Finally, removing the iptables rule allows the pending Web connections to succeed. Since the whole thing took only about 30 seconds, it shouldn&#8217;t cause a browser error &#8212; to the visitor, it just seems like a page took longer than normal to display. A slow page load is obviously an annoyance (and we normally only do this kind of upgrade in the wee hours of weekends to minimize that annoyance), but it&#8217;s much better than a visitor receiving a &#8220;database connection failed&#8221; error when they try to place an order on your online store, etc.</p>
<p>By the way, the above example doesn&#8217;t cover the possibility that MySQL connections could be opened by non-Web processes like cron jobs, and it doesn&#8217;t handle connections that take longer than 15 seconds to finish. You could automate this with a little shell scripting that queries MySQL to see if all connections are closed, but we just watch it from a different terminal window to make sure.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/mysql-and-php-5-security-updates/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Unscheduled network outage (resolved)</title>
		<link>http://blog.tigertech.net/posts/unscheduled-network-outage-resolved/</link>
		<comments>http://blog.tigertech.net/posts/unscheduled-network-outage-resolved/#comments</comments>
		<pubDate>Fri, 11 Jan 2008 07:16:07 +0000</pubDate>
		<dc:creator>Robert Mathews</dc:creator>
		
		<category><![CDATA[System Status]]></category>

		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[status]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/posts/unscheduled-network-outage-resolved/</guid>
		<description><![CDATA[Between 9:52 and 11:06 PM Pacific time on January 10, a complete network failure at our primary data center caused an unscheduled outage that resulted in all services (all Web sites and e-mail) being unreachable from the Internet.
This problem has been resolved and all services are now available. We are waiting for a full report [...]]]></description>
			<content:encoded><![CDATA[<p>Between 9:52 and 11:06 PM Pacific time on January 10, a complete network failure at our primary data center caused an unscheduled outage that resulted in all services (all Web sites and e-mail) being unreachable from the Internet.</p>
<p>This problem has been resolved and all services are now available. We are waiting for a full report from the data center personnel so that we can determine the cause and ensure that it won&#8217;t recur.</p>
<p>We sincerely apologize to our customers who were affected by this. This kind of outage is not normal (it&#8217;s the longest outage we&#8217;ve experienced in more than four years), and we know it&#8217;s not acceptable to our customers who rely on our services. We&#8217;ll post a followup message with more details when they become available.</p>
<p><em>Update Friday 10 AM</em>: As a clarification, we should also have originally mentioned that no e-mail is lost during this kind of outage: it&#8217;s delivered after the issue is resolved. While some messages were certainly delayed, they were all properly delivered afterward.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/unscheduled-network-outage-resolved/feed/</wfw:commentRss>
		</item>
		<item>
		<title>New locales available for scripts</title>
		<link>http://blog.tigertech.net/posts/new-locales/</link>
		<comments>http://blog.tigertech.net/posts/new-locales/#comments</comments>
		<pubDate>Tue, 08 Jan 2008 19:48:50 +0000</pubDate>
		<dc:creator>Robert Mathews</dc:creator>
		
		<category><![CDATA[Tech Corner]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/posts/new-locales/</guid>
		<description><![CDATA[A customer pointed out that our servers didn&#8217;t have many &#8220;locales&#8221; installed. A &#8220;locale&#8221; is a set of rules that apply to a language, region or culture &#8212; things like the language&#8217;s words for &#8220;January&#8221; and &#8220;Monday&#8221;, the way that dates are displayed, and the currency symbol used.

Locales are useful, because when they&#8217;re available, a [...]]]></description>
			<content:encoded><![CDATA[<p>A customer pointed out that our servers didn&#8217;t have many &#8220;locales&#8221; installed. A &#8220;<a href="http://en.wikipedia.org/wiki/Locale">locale</a>&#8221; is a set of rules that apply to a language, region or culture &#8212; things like the language&#8217;s words for &#8220;January&#8221; and &#8220;Monday&#8221;, the way that dates are displayed, and the currency symbol used.</p>
<p><span id="more-97"></span></p>
<p>Locales are useful, because when they&#8217;re available, a script can easily generate things like dates in different languages. For example, this script:</p>
<pre>
&lt;?php
  echo strftime("%A %E %B %Y");
?&gt;</pre>
<p>&#8230; will normally print &#8220;Tuesday  8 January 2008&#8243;. But if the French locale is available, adding one line:</p>
<pre>
&lt;?php
  setlocale(LC_ALL, 'fr_FR');
  echo strftime("%A %E %B %Y");
?&gt;</pre>
<p>&#8230; will print &#8220;mardi  8 janvier 2008&#8243; instead.</p>
<p>So having many locales available on a server makes it easy for scripts to show dates and other information in ways beyond the standard &#8220;US English&#8221; display.</p>
<p>As of today, we&#8217;ve installed many extra locales on our servers for English, French, German, Italian and Spanish languages. (All these languages have more than one actual locale, because the English language, for example, uses different currency symbols and date formats depending on which country you&#8217;re in.) We hope some customers find this useful.</p>
<p>For more information about changing locales in a script, see the &#8220;setlocale()&#8221; command in your favorite programming language. Advanced users can get a full list of the available locales on the server by making a <a href="http://support.tigertech.net/shell">shell connection</a> and typing &#8220;locale -a&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/new-locales/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Temporary decrease in spam filtering (resolved)</title>
		<link>http://blog.tigertech.net/posts/temporary-decrease-in-spam-filtering-resolved/</link>
		<comments>http://blog.tigertech.net/posts/temporary-decrease-in-spam-filtering-resolved/#comments</comments>
		<pubDate>Thu, 27 Dec 2007 23:17:33 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
		
		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[e-mail]]></category>

		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/posts/temporary-decrease-in-spam-filtering-resolved/</guid>
		<description><![CDATA[On the morning of December 25, a technical problem with our spam filters allowed more spam than usual for several hours. Customers may have seen a spike in spam arriving during that period.
We found and fixed the root cause of the problem, and it won&#8217;t occur again.
We apologize for any inconvenience this may have caused. [...]]]></description>
			<content:encoded><![CDATA[<p>On the morning of December 25, a technical problem with our spam filters allowed more spam than usual for several hours. Customers may have seen a spike in spam arriving during that period.</p>
<p>We found and fixed the root cause of the problem, and it won&#8217;t occur again.</p>
<p>We apologize for any inconvenience this may have caused. We know that no one wanted more spam for Christmas!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/temporary-decrease-in-spam-filtering-resolved/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Oddities with the MySQL &#8220;Table upgrade required&#8221; message</title>
		<link>http://blog.tigertech.net/posts/mysql-table-upgrade-required/</link>
		<comments>http://blog.tigertech.net/posts/mysql-table-upgrade-required/#comments</comments>
		<pubDate>Fri, 07 Dec 2007 22:46:55 +0000</pubDate>
		<dc:creator>Robert Mathews</dc:creator>
		
		<category><![CDATA[Tales From the Support Team]]></category>

		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/posts/mysql-table-upgrade-required/</guid>
		<description><![CDATA[Here&#8217;s an obscure thing we spent some time on today that doesn&#8217;t affect our customers, but might be useful to someone else searching the Internet. The problem was a MySQL database table that, as far as we can tell, worked perfectly&#8230; except that it shows this message when we run CHECK TABLE:
Table upgrade required. Please [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s an obscure thing we spent some time on today that doesn&#8217;t affect our customers, but might be useful to someone else searching the Internet. The problem was a MySQL database table that, as far as we can tell, worked perfectly&#8230; except that it shows this message when we run <tt>CHECK TABLE</tt>:</p>
<p><code>Table upgrade required. Please do "REPAIR TABLE `users`" to fix it!</code></p>
<p><span id="more-92"></span></p>
<p>Hmm. Well, that error message seems odd, but what the heck. After making sure there&#8217;s a current backup, let&#8217;s give it a shot:</p>
<pre>
mysql&gt; REPAIR TABLE users;

+---------------------+--------+----------+-----------------------------+
| Table               | Op     | Msg_type | Msg_text                    |
+---------------------+--------+----------+-----------------------------+
| database.users      | repair | status   | Table is already up to date |
+---------------------+--------+----------+-----------------------------+</pre>
<p>And yet, <tt>CHECK TABLE</tt> still says there&#8217;s a problem:</p>
<pre>
mysql&gt; CHECK TABLE users;

+---------------------+-------+----------+-------------------------------------+
| Table               | Op    | Msg_type | Msg_text                            |
+---------------------+-------+----------+-------------------------------------+
| database.users      | check | error    | Table upgrade required. Please do   |
|                     |       |          |  "REPAIR TABLE `users`" to fix it!  |
+---------------------+-------+----------+-------------------------------------+</pre>
<p>Hmmm. We tried every reasonable combination of <tt>REPAIR TABLE</tt> and <tt>myisamchk</tt> options we could think of, but nothing helped. Then we tried unreasonable options, including the frightening <tt>REPAIR TABLE table USE_FRM</tt> option. In our experience <tt>USE_FRM</tt> usually ends up doing the same thing as <tt>DELETE FROM table</tt>, and this time was no exception. (And <strong>that&#8217;s</strong> why you make a backup first.)</p>
<p>Well, let&#8217;s take a look at the table status (with the uninteresting bits removed):</p>
<pre>
mysql&gt; show table status;

+-------+--------+---------+-----+---------------------+
| Name  | Engine | Version | ... | Create_time         |
+-------+--------+---------+-----+---------------------+
| good  | MyISAM |      10 | ... | 2007-06-08 09:44:01 |
| users | MyISAM |       7 | ... | 2005-03-15 12:03:11 |
+-------+--------+---------+-----+---------------------+</pre>
<p>Sure enough, the bad &#8220;users&#8221; table is a different version than a good table that doesn&#8217;t have this problem. And the bad table was created when we were still using MySQL 4.1.x. This table should have been changed when we upgraded to MySQL 5, and it should be possible to fix now. Why on earth won&#8217;t <tt>REPAIR TABLE</tt> fix it?</p>
<p>We puzzled over this for some time, and eventually just decided to reload it from a dump. But here&#8217;s the strange thing: it wouldn&#8217;t reload from the dump, either!</p>
<p><code>ERROR 1060 (42S21) at line 20: Duplicate column name 'user_id'</code></p>
<p>What the heck? So we looked closely at the dump file, and it somehow contains this line:</p>
<p><code>PRIMARY KEY  (user_id,user_id)</code></p>
<p>MySQL thinks this table has a composite (two-column) primary key, but on the same column twice, which doesn&#8217;t make any sense. So we fix the dump to look like this:</p>
<p><code>PRIMARY KEY  (user_id)</code></p>
<p>And everything works perfectly when the table is reloaded.</p>
<p>So if <tt>CHECK TABLE</tt> tells you a table upgrade is required, but <tt>REPAIR TABLE</tt> won&#8217;t fix it, check whether you can actually reload a dump of that table. You might find something unusual and easily fixable in the dump.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/mysql-table-upgrade-required/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL Security Update</title>
		<link>http://blog.tigertech.net/posts/mysql-security-update/</link>
		<comments>http://blog.tigertech.net/posts/mysql-security-update/#comments</comments>
		<pubDate>Fri, 07 Dec 2007 06:10:24 +0000</pubDate>
		<dc:creator>Robert Mathews</dc:creator>
		
		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[mysql]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[server updates]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/posts/mysql-security-update/</guid>
		<description><![CDATA[We applied a MySQL security update tonight. The version number remains 5.0.32, and customers should not notice any changes; the update just fixes several security issues.
The update was performed in such a way that new Web server connections were delayed during the 30 seconds or so that MySQL was unavailable on each server. That should [...]]]></description>
			<content:encoded><![CDATA[<p>We applied a MySQL <a href="/posts/security-updates/">security update</a> tonight. The version number remains 5.0.32, and customers should not notice any changes; the update just fixes <a href="http://lists.debian.org/debian-security-announce-07/msg00193.html">several security issues</a>.</p>
<p>The update was performed in such a way that new Web server connections were delayed during the 30 seconds or so that MySQL was unavailable on each server. That should mean that as far as scripts on your Web site were concerned, there was zero MySQL downtime.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/mysql-security-update/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Software updates: Ruby on Rails, phpMyAdmin, WordPress</title>
		<link>http://blog.tigertech.net/posts/software-updates-2007-11-27/</link>
		<comments>http://blog.tigertech.net/posts/software-updates-2007-11-27/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 00:36:05 +0000</pubDate>
		<dc:creator>Robert Mathews</dc:creator>
		
		<category><![CDATA[Tech Corner]]></category>

		<category><![CDATA[phpmyadmin]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[server updates]]></category>

		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://blog.tigertech.net/posts/software-updates-phpmyadmin-ruby-on-rails-wordpress/</guid>
		<description><![CDATA[We&#8217;ve updated several things on our servers today:

Ruby on Rails was updated from version 1.2.3 to 1.2.6. (If you use Rails on your site, our page explaining how to freeze Rails explains how you can get total control of Rails updates.)
phpMyAdmin was updated from version 2.11.2.1 to 2.11.2.2.
The WordPress software that runs this blog was [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve updated several things on our servers today:</p>
<ul>
<li><a href="http://support.tigertech.net/ruby">Ruby on Rails</a> was updated from version 1.2.3 to 1.2.6. (If you use Rails on your site, our page explaining how to <a href="http://support.tigertech.net/freeze-rails">freeze Rails</a> explains how you can get total control of Rails updates.)</li>
<li><a href="http://support.tigertech.net/phpmyadmin">phpMyAdmin</a> was updated from version 2.11.2.1 to 2.11.2.2.</li>
<li>The WordPress software that runs this blog was updated to version 2.3.1. That doesn&#8217;t directly affect our customers &#8212; but if you&#8217;ve installed your own version of WordPress on your own site, this is a good reminder to update it: some older versions have security vulnerabilities. (We found that the update from 2.2.X to 2.3.1 was painless.)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.tigertech.net/posts/software-updates-2007-11-27/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.471 seconds -->
