<?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>Hack MySQL Blog &#187; Programming</title>
	<atom:link href="http://hackmysql.com/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://hackmysql.com/blog</link>
	<description>Dolphins and camels, oh my!</description>
	<lastBuildDate>Wed, 26 May 2010 23:48:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Down the rabbit hole</title>
		<link>http://hackmysql.com/blog/2010/05/25/down-the-rabbit-hole/</link>
		<comments>http://hackmysql.com/blog/2010/05/25/down-the-rabbit-hole/#comments</comments>
		<pubDate>Tue, 25 May 2010 22:28:43 +0000</pubDate>
		<dc:creator>Daniel Nichter</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[mk-table-checksum]]></category>
		<category><![CDATA[rabbit]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://hackmysql.com/blog/?p=112</guid>
		<description><![CDATA[Generally I avoid going down rabbit holes but today I decided to see how deep a particular testing rabbit hole went.  This post is a third in what seems be a continuing series of programming anecdotes.  It&#8217;s not particularly MySQL-related so you can stop reading here unless you grok code stuff.
Before beginning work [...]]]></description>
			<content:encoded><![CDATA[<p>Generally I avoid going down rabbit holes but today I decided to see how deep a particular testing rabbit hole went.  This post is a third in what seems be a continuing series of <a href="http://hackmysql.com/blog/category/programming/">programming anecdotes</a>.  It&#8217;s not particularly MySQL-related so you can stop reading here unless you grok code stuff.</p>
<p>Before beginning work on <a href="http://code.google.com/p/maatkit/issues/detail?id=720">issue 720</a> I ran the mk-table-checksum test suite to make sure it was in working order. No sense writing new tests and code when the old tests and code aren&#8217;t reliable.  I actually made one seemingly innocuous change to the test suite in preparation for the issue: I changed the &#8211;replicate checksum table from MyISAM to InnoDB.</p>
<p>Surprisingly, the test suite proved unstable.  Random tests would fail at random times. Some instability was due to new tests for other issues that I wrote poorly and hadn&#8217;t been run a zillion times yet.  But other instability was due to switching the checksum table to InnoDB.  I knew this because I could switch it back to InnoDB and the tests were ok.  Thus began my descent into the rabbit hole.</p>
<p>In particular the test for <a href="http://code.google.com/p/maatkit/issues/detail?id=982">issue 982</a> was not finishing or, if it did, it took forever.  I discovered that the problem had to do with &#8211;lock even though it shouldn&#8217;t since the docu says that &#8211;replicate and &#8211;lock are useless together because the former eliminates locking concerns.  Obviously not.  So for this I created <a href="http://code.google.com/p/maatkit/issues/detail?id=1027">issue 1027</a>.</p>
<p>Then I turned my attention to test 207_issue_51.t for <a href="http://code.google.com/p/maatkit/issues/detail?id=51">issue 51</a> which was opened 2 years ago and closed 1 year ago as WontFix because the problem could not be reproduced.  Some might have thought it forgotten amongst the nearly 1,000 issues since its time, but it was found again at the end of this rabbit hole and revivified.</p>
<p>It turns out that issue 51 is, as the original reporter stated (partially), caused by &#8211;wait when (this is the part the original reporter didn&#8217;t state) the &#8211;replicate checksum table is InnoDB because &#8211;wait enables &#8211;lock which disables AutoCommit so writes to the checksum table may not be committed.</p>
<p>So the rabbit hole lead from issue 720 to issue 982 to issue 1027 to issue 51.  Then end results will be a needed bug fix and faster, more stable tests.  Sometimes it pays to follow the rabbit.</p>
]]></content:encoded>
			<wfw:commentRss>http://hackmysql.com/blog/2010/05/25/down-the-rabbit-hole/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging and ripple effects</title>
		<link>http://hackmysql.com/blog/2009/11/18/debugging-and-ripple-effects/</link>
		<comments>http://hackmysql.com/blog/2009/11/18/debugging-and-ripple-effects/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 22:58:01 +0000</pubDate>
		<dc:creator>Daniel Nichter</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[mk-query-digest]]></category>

		<guid isPermaLink="false">http://hackmysql.com/blog/?p=92</guid>
		<description><![CDATA[Like I said earlier, every tiny change that the test suite reveals after code changes is significant.  I caught a very subtle &#8220;bug&#8221; today in recent changes to mk-query-digest (a.k.a. mqd).  If you like to read about subtle bugs, read on.
An mqd test on sample file slow023.txt began to differ after some pretty [...]]]></description>
			<content:encoded><![CDATA[<p>Like I <a href="http://hackmysql.com/blog/2009/10/30/zero-is-a-big-number/">said earlier</a>, every tiny change that the test suite reveals after code changes is significant.  I caught a very subtle &#8220;bug&#8221; today in recent changes to mk-query-digest (a.k.a. mqd).  If you like to read about subtle bugs, read on.</p>
<p>An mqd test on sample file slow023.txt began to differ after some pretty extensive code changes of late:<br />
<code><br />
< # Query 1: 0 QPS, 0x concurrency, ID 0x8E38374648788E52 at byte 0 ________<br />
---<br />
> # Query 1: 0 QPS, 0x concurrency, ID 0x2CFD93750B99C734 at byte 0 ________<br />
</code><br />
The ID which depends on the query&#8217;s fingerprint has changed.  It&#8217;s very important that we don&#8217;t suddenly change these on users because these IDs are pivotal in trend analyses with mqd&#8217;s <code>--review-history</code> option. First some background info on the recent code changes and then the little story about how I tracked down the source of this change.</p>
<p>mqd internals used to run like this: call parser module (like SlowLogParser) and pass it an array of callbacks which it ran events through.  Now this has changed so there&#8217;s a single, unified pipeline of &#8220;callbacks&#8221; (they&#8217;re technically no longer callbacks).  The first process in the pipeline is usually a parser module which returns each event and then mqd keeps pumping the events through the pipeline (in contrast to before where the parser module did the pumping).  So &#8220;obviously&#8221; this has nothing to do with query fingerprinting or ID making which is done in code that has not changed.  Thus, this &#8220;bug&#8221; was very perplexing at first.</p>
<p>First step: see what value <code>make_checksum()</code>, which makes the query IDs, used to get and gets now by using the Perl debugger:<br />
<code><br />
DB<3> x $item<br />
0  'select count(*) as a from x '<br />
</code><br />
<code><br />
DB<12> x $item<br />
0  'select count(*) as a from x'<br />
</code><br />
The difference is that single trailing space. But why has this space suddenly disappeared in the new (later) rev? Something in <code>fingerprint()</code> must have changed, which is the sub that makes that query.  Use the debugger again to step through <code>fingerprint()</code> while a watch is set on the var:<br />
<code><br />
1574:	   $query =~ s/\A\s+//;                  # Chop off leading whitespace<br />
  DB<6><br />
Watchpoint 0:	$query changed:<br />
    old value:	' select count(*) as A from X<br />
'<br />
    new value:	'select count(*) as A from X<br />
'<br />
QueryRewriter::fingerprint(bin/mk-query-digest:1575):<br />
1575:	   chomp $query;                         # Kill trailing whitespace<br />
  DB<6><br />
QueryRewriter::fingerprint(bin/mk-query-digest:1576):<br />
1576:	   $query =~ tr[ \n\t\r\f][ ]s;          # Collapse whitespace<br />
  DB<6><br />
Watchpoint 0:	$query changed:<br />
    old value:	'select count(*) as A from X<br />
'<br />
    new value:	'select count(*) as A from X '<br />
</code><br />
Notice that the var did not change after the line &#8220;# Kill trailing whitespace&#8221; was executed.  The trailing newline was removed and reduced to a single trailing space when &#8220;# Collapse whitespace&#8221; was executed.  The new rev:<br />
<code><br />
1585:	   $query =~ s/\A\s+//;                  # Chop off leading whitespace<br />
  DB<4><br />
Watchpoint 0:	$query changed:<br />
    old value:	' select count(*) as A from X<br />
'<br />
    new value:	'select count(*) as A from X<br />
'<br />
QueryRewriter::fingerprint(../mk-query-digest:1586):<br />
1586:	   chomp $query;                         # Kill trailing whitespace<br />
  DB<4><br />
Watchpoint 0:	$query changed:<br />
    old value:	'select count(*) as A from X<br />
'<br />
    new value:	'select count(*) as A from X'<br />
</code><br />
Notice how <code>chomp</code> in the new rev removed all trailing whitespace; the result of <code>chomp</code> has changed, but why?  In case you didn&#8217;t know, <code>chomp</code> actually chomps any trailing <code>$INPUT_RECORD_SEPARATOR</code>, not just newlines.  It just so happens that many of the parser modules change <code>$INPUT_RECORD_SEPARATOR</code>.</p>
<p>The root of this subtle but very important change is due to the fact that the parser modules no longer call the pipeline callbacks.  When they did, their changes to <code>$INPUT_RECORD_SEPARATOR</code> were visible to the callbacks, and operations like <code>fingerprint()</code> are part of the callbacks.  Now that they do not, their changes to <code>$INPUT_RECORD_SEPARATOR</code> are &#8220;invisible&#8221; and operations like <code>fingerprint()</code> see a different (i.e. the default) <code>$INPUT_RECORD_SEPARATOR</code>.</p>
<p>Conclusion in brief: an issue of scope at the beginning of mk-query-digest affects <code>chomp</code> causing <code>fingerprint()</code> and <code>make_checksum()</code> to generate different query IDs at the end of the script.</p>
]]></content:encoded>
			<wfw:commentRss>http://hackmysql.com/blog/2009/11/18/debugging-and-ripple-effects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zero is a big number</title>
		<link>http://hackmysql.com/blog/2009/10/30/zero-is-a-big-number/</link>
		<comments>http://hackmysql.com/blog/2009/10/30/zero-is-a-big-number/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 15:20:30 +0000</pubDate>
		<dc:creator>Daniel Nichter</dc:creator>
				<category><![CDATA[Maatkit]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[mk-query-digest]]></category>

		<guid isPermaLink="false">http://hackmysql.com/blog/?p=70</guid>
		<description><![CDATA[I made changes to mk-query-digest yesterday that I didn&#8217;t expect to cause any adverse affects.  On the contrary, several tests began to fail because a single new but harmless line began to appear in the expected output: &#8220;Databases 0&#8243;.  Perhaps I&#8217;m preaching to the choir, as you are all fantastic, thorough and flawless [...]]]></description>
			<content:encoded><![CDATA[<p>I made changes to mk-query-digest yesterday that I didn&#8217;t expect to cause any adverse affects.  On the contrary, several tests began to fail because a single new but harmless line began to appear in the expected output: &#8220;Databases 0&#8243;.  Perhaps I&#8217;m preaching to the choir, as you are all fantastic, thorough and flawless programmers, but as for myself I&#8217;ve learned to never take a single failed test for granted.</p>
<p>One time a test failed because some values differed by a millisecond or two.  Being curious I investigated and found that our standard deviation equation was just shy of perfect.  I fixed it and spent hours cross-checking the myriad tiny values with my TI calculator. Probably no one cared about 0.023 vs. 0.022 but it&#8217;s the cultivation of a disposition towards perfection that matters.</p>
<p>My innocuous changes yesterday introduced a case of Perl auto-vivification.  Doing:</p>
<p><code>my ($db_for_show) = $sample->{db} ? $sample->{db} : keys %{$stats->{db}->{unq}};</code></p>
<p>can auto-vivify <code>$stats->{db}</code>.  Before yesterday, this was done before the report for those stats were printed; changes yesterday made this happen after the report.  Thus the report did it&#8217;s job and reported <code>db</code> or &#8220;Databases 0&#8243;.  It&#8217;s been fixed, and just in time since I&#8217;m doing Maatkit&#8217;s October release today.</p>
]]></content:encoded>
			<wfw:commentRss>http://hackmysql.com/blog/2009/10/30/zero-is-a-big-number/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
