<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://www.skepticats.com/LnBlog/themes/default/styles/rss.css" ?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<link>http://linlog.skepticats.com/feeds/Programming_news.xml</link>
<title>LinLog</title>
<description>Linux, Programming, and Computing in General</description>
<generator>LnBlog 1.0.0</generator>
<item>
<title>Up 79 million in 20 seconds      </title>
<link>http://linlog.skepticats.com/entries/2008/11/Up_79_million_in_20_seconds.php</link>
<description>
&lt;p&gt;We had one of those weird experiences at work today.  The kind where something strange happens, and nobody knows how or why, and when you look into it, it doesn't even make sense.&lt;/p&gt;&lt;p&gt;Basically, the auto-numbered ID field on the table we use for media items (videos, pictures, etc.) jump up noticably this morning.  And by &amp;quot;noticably&amp;quot; I mean it went from about 1 million to about 80 million.  And when we looked at the timestamps, the jump happened in about 20 seconds.  The IDs created before 8:38:12 AM were in teh 1 million range, and the ones createdafter 8:38:32 AM were in the 80 million range.  &lt;/p&gt;&lt;p&gt;So the obvious question is: how did this happen?  It doesn't look like it was caused by actually adding 79 million records to the table.  There were only about 800,000 records total, and no indication in our moderation logs of any mass deletions.  We didn't get any indication of increased server load either.  In fact, the only reason we even noticed it is because the media IDs are in our URLs.  I kind of doubt a bot could have created 79 million new media items in 20 seconds without at least generating a Nagios warning.  In fact, I doubt our master database server could &lt;em&gt;handle&lt;/em&gt; 79 million writes in 20 seconds.&lt;/p&gt;&lt;p&gt;So what does that leave?  User error?  Nobody with access to the database server was even working at 8:30 in the morning.  Random MySQL screw up?  Maybe, though that's a really wierd random error.  Something else?  Who knows...?&lt;/p&gt;&lt;p&gt;After sniffing around the server and tossing out ideas for 30 or 40 minutes, we ultimately gave up.  It's a little disquieting that we don't know what happened, but we really can't justify spending all that much time on this.  It's a very weird problem, but nothing is broken and we all have more important things to worry about at the moment.  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; Found the cause.  &lt;a href=&quot;http://linlog.skepticats.com/entries/2008/12/Apparently_we_were__hacked_.php&quot;&gt;Apparently we were hacked&lt;/a&gt;.&lt;/p&gt;
</description>
<author>pageer@skepticats.com (Peter Geer)</author>
<comments>http://linlog.skepticats.com/entries/2008/11/24_2154/comments/</comments>
<guid>http://linlog.skepticats.com/entries/2008/11/24_2154/</guid>
</item>
<item>
<title>Weird index breakage   </title>
<link>http://linlog.skepticats.com/entries/2008/10/Weird_index_breakage.php</link>
<description>
&lt;p&gt;Here's an odd one.  So I was trying to run a simple query for a data import I'm working on.  I've got about 11,000 rows in the media table with a site_id of 2 and I wanted to see which media types were represented.  So I ran this:&lt;/p&gt;&lt;p&gt;&lt;code&gt;SELECT DISTINCT media_type FROM media WHERE site_id = 2;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;To my surprise, this returned...nothing!  No rows at all.  So I took off the &lt;code&gt;DISTINCT&lt;/code&gt;, just to check, and got back all 11,000 rows.  What the heck?&lt;/p&gt;&lt;p&gt;Something was obviously wrong.  This should never happen - if there are rows with the correct site_id, that query should always return &lt;em&gt;something&lt;/em&gt;.  So what now?  Might as well look at the query plan:&lt;/p&gt;&lt;p&gt;&lt;code&gt;mysql&amp;gt; explain extended select distinct media_type from media where site_id = 2 \G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;           id: 1&lt;br /&gt;  select_type: SIMPLE&lt;br /&gt;        table: media&lt;br /&gt;         type: range&lt;br /&gt;possible_keys: idx_media_site_media_type,idx_frontpage&lt;br /&gt;          key: idx_typesiteid&lt;br /&gt;      key_len: 2&lt;br /&gt;          ref: NULL&lt;br /&gt;         rows: 15&lt;br /&gt;        Extra: Using where; Using index for group-by&lt;br /&gt;1 row in set, 1 warning (0.00 sec)&lt;/p&gt;&lt;p&gt;mysql&amp;gt; show warnings \G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;  Level: Note&lt;br /&gt;   Code: 1003&lt;br /&gt;Message: select distinct `cms`.`media`.`media_type` AS `media_type` from `cms`.`media` where (`cms`.`media`.`site_id` = 2)&lt;br /&gt;1 row in set (0.00 sec)&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Nothing out of the ordinary there.  It's using the idx_typesiteid index, which is correct.  Maybe that index is broken.  Let's try another one:&lt;/p&gt;&lt;p&gt;&lt;code&gt;select distinct media_type from media use index (idx_media_site_media_type) where site_id = 2;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Yup, it worked that time - I got 5 rows back, which is about what I was expecting.  I get the same results if I use &lt;br /&gt;&lt;code&gt;IGNORE INDEX (idx_typesiteid)&lt;/code&gt; as the index hint.  So idx_typesiteid must just be broken.  I should probably fix that, but it was getting into peak hours for our site and I didn't want to run an &lt;code&gt;OPTIMIZE TABLE&lt;/code&gt; or anything that would lock the media table.&lt;/p&gt;&lt;p&gt;But wait, there's one other weird thing.  Just for the heck of it, I tried running the query with a few different index hints.  And guess what: the query still works if I use &lt;code&gt;FORCE INDEX (idx_typesiteid)&lt;/code&gt;.  Does that make sense to anybody?  So if I &lt;em&gt;ignore&lt;/em&gt; that index it works, and if I &lt;em&gt;force&lt;/em&gt; the same index, it works, but if I give no hint, it claims to use that index and the query returns no data.  I got nothin' on that one.&lt;/p&gt;
</description>
<author>pageer@skepticats.com (Peter Geer)</author>
<comments>http://linlog.skepticats.com/entries/2008/10/30_2322/comments/</comments>
<guid>http://linlog.skepticats.com/entries/2008/10/30_2322/</guid>
</item>
<item>
<title>MySQL comment weirdness </title>
<link>http://linlog.skepticats.com/entries/2008/10/MySQL_comment_weirdness.php</link>
<description>
&lt;p&gt;Here's one I discovered for the first time yesterday - &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/comments.html&quot;&gt;MySQL doesn't actually use the ANSI SQL comment sequence&lt;/a&gt;.  Who knew?&lt;/p&gt;&lt;p&gt;For those who are a little rusty on such things, ANSI SQL-92 specifies the comment character as a doule dash (--).  Anything from a double dash to the end of a line is a comment.&lt;/p&gt;&lt;p&gt;Well, in MySQL, that doesn't actually work.  You &lt;em&gt;have&lt;/em&gt; to have a &lt;em&gt;space&lt;/em&gt; (or control character) after the double dash for MySQL to treat is as a comment.  This is good style anyway, but MySQL makes it a hard requirement.  Apparently the &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html&quot;&gt;reason for this&lt;/a&gt; is that it can cause conflicts with software that auto-generates really crappy queries.  &lt;/p&gt;&lt;p&gt;Is it just me, or does that seem like a really gratuitous change?  I mean, I can see their reasons - it would be nice if an auto-generated query like &lt;code&gt;UPDATE account SET credit=credit--1&lt;/code&gt; actually worked instead of reducing to a no-op.  But, on the other hand, is it really a good idea to change the database server because some vendor is too lazy to make their query-generator produce the more correct and logically equivalent &lt;code&gt;UPDATE account SET credit=credit+1&lt;/code&gt; instead?  I don't know.  I'm sure they had their reasons, but it just feels like a half-baked hack to me.&lt;/p&gt;
</description>
<author>pageer@skepticats.com (Peter Geer)</author>
<comments>http://linlog.skepticats.com/entries/2008/10/14_2333/comments/</comments>
<guid>http://linlog.skepticats.com/entries/2008/10/14_2333/</guid>
</item>
<item>
<title>Updating from the same table     </title>
<link>http://linlog.skepticats.com/entries/2008/06/Updating_from_the_same_table.php</link>
<description>
&lt;p&gt;Last time, I was bitching about &lt;a href=&quot;http://linlog.skepticats.com/entries/2008/06/Another_reason_to_hate_MySQL.php&quot;&gt;doing an update based on a select from the same table in MySQL&lt;/a&gt;.  Well, after reading the chapter on &amp;quot;Views, Derived Tables, Materialized Tables, and Temporary Tables&amp;quot; in &lt;em&gt;SQL for Smarties&lt;/em&gt;, followed by a search of the MySQL documentation, I figured out a way around that annoying limitation.&lt;/p&gt;&lt;p&gt;If you recall from last time, the query that wasn't working looked something like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mysql&amp;gt; UPDATE test_tbl SET val2 = (SELECT val2 FROM test_tbl WHERE val1 = 1) WHERE val1 = 3;&lt;br /&gt;ERROR 1093 (HY000): You can't specify target table 'test_tbl' for update in FROM clause&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Basically, this is doing an update and setting a column to the value of a scalar subquery.  The catch is that, in MySQL, this doesn't work when the select and update are on the same table.&lt;/p&gt;&lt;p&gt;Well, the trick is that you have to make make MySQL materialize the subquery.  I actually decided to try that after reading Joe Celko's story about views in the early days of DB2.  At the time, it was using inline-expansion for views, which would sometimes generate invalid SQL.  Thus it was sometimes necessary to make the database materialize the view.  &lt;/p&gt;&lt;p&gt;Well, I figured the same thing might apply here.  And so, after a little inspiration from the MySQL manual, here's a working version of the same query:&lt;/p&gt;&lt;p&gt;&lt;code&gt;UPDATE test_tbl SET val2 = (SELECT val2 FROM (SELECT val2 FROM test_tbl AS tmp1 WHERE val1=1) AS tmp2) WHERE val1 = 3;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;I stole &lt;a href=&quot;http://dev.mysql.com/doc/refman/4.1/en/subquery-restrictions.html&quot;&gt;the sub-subquery idea&lt;/a&gt; from the MySQL manual.  It is, of course, completely gratuitous from a logical standpoint, but it forces MySQL to materialize the subquery.  That, in turn, allows us to bypass the &amp;quot;no updating the same table&amp;quot; restriction, since we're technically selecting from a temporary table.&lt;/p&gt;&lt;p&gt;So there you have it!  I was wrong about not being able to do that.  It just takes a little finagling.  Of course, I still think MySQL should be smart enough to make a temporary table on its own, but at least the end result is still possible.&lt;/p&gt;
</description>
<author>pageer@skepticats.com (Peter Geer)</author>
<comments>http://linlog.skepticats.com/entries/2008/06/16_1401/comments/</comments>
<guid>http://linlog.skepticats.com/entries/2008/06/16_1401/</guid>
</item>
</channel>
</rss>