<?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>domas mituzas: vaporware, inc.</title>
	<atom:link href="http://mituzas.lt/feed/" rel="self" type="application/rss+xml" />
	<link>http://mituzas.lt</link>
	<description>where ideas come and die</description>
	<lastBuildDate>Fri, 26 Feb 2010 15:05:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0-alpha</generator>
		<item>
		<title>Opening tables v2!</title>
		<link>http://mituzas.lt/2010/02/26/opening-tables-v2/</link>
		<comments>http://mituzas.lt/2010/02/26/opening-tables-v2/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 15:04:51 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=725</guid>
		<description><![CDATA[PMP on demand revealed one of reasons why we&#8217;ve been seeing &#8216;Opening tables&#8217; during proper operations, not just during startup (see my previous post on this topic).
We had a thousand or so threads waiting on LOCK_open, and the only thread holding the mutex was this darling:

Thread 902 (Thread 1637624128 (LWP 22113)):
#3  mutex_spin_wait (mutex=0x2aaaac3232b8,
  [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://poormansprofiler.org'>PMP</a> on demand revealed one of reasons why we&#8217;ve been seeing &#8216;Opening tables&#8217; during proper operations, not just during startup (see my <a href='http://mituzas.lt/2009/12/26/opening-tables/'>previous post</a> on this topic).</p>
<p>We had a thousand or so threads waiting on LOCK_open, and the only thread holding the mutex was this darling:</p>
<pre>
Thread 902 (Thread 1637624128 (LWP 22113)):
#3  mutex_spin_wait (mutex=0x2aaaac3232b8,
        file_name=0x8b3bf7 "trx0trx.c", line=220) at sync0sync.c:565
#4  trx_allocate_for_mysql
#5  ha_innobase::allocate_trx
#6  check_trx_exists
#7  ha_innobase::info
#8  ha_innobase::open
#9  handler::ha_open
#10 openfrm
#11 open_unireg_entry
#12 open_table
#13 open_tables
#14 open_and_lock_tables
#15 mysql_insert
</pre>
<p>So, kernel mutex, which is quite contended, will escalate to LOCK_open on table open, which will block all queries from happening on the server. Fix? Nearly same code as previous &#8220;Opening tables&#8221; fix &#8211; don&#8217;t call ha_innobase::info() as part of open(), or move the transaction establishment code outside of info(). </p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2010/02/26/opening-tables-v2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Read ahead&#8230;</title>
		<link>http://mituzas.lt/2010/01/02/read-ahead/</link>
		<comments>http://mituzas.lt/2010/01/02/read-ahead/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 11:00:43 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[gdb]]></category>
		<category><![CDATA[innodb]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=720</guid>
		<description><![CDATA[Mark wrote about how to find situations where InnoDB read-ahead is a bottleneck. What he didn&#8217;t disclose, though, is his trick to disable read-ahead without restart or recompile of MySQL. See, there&#8217;s no internal &#8220;disable read ahead knob&#8221;. But there is&#8230;

buf_read_ahead_random(...){ ...
       if (srv_startup_is_before_trx_rollback_phase) {
     [...]]]></description>
			<content:encoded><![CDATA[<p>Mark <a href="http://www.facebook.com/notes/mysqlfacebook/when-doesnt-innodb-readahead-work/198536580932">wrote</a> about how to find situations where InnoDB read-ahead is a bottleneck. What he didn&#8217;t disclose, though, is his trick to disable read-ahead without restart or recompile of MySQL. See, there&#8217;s no internal &#8220;disable read ahead knob&#8221;. But there is&#8230;</p>
<pre>
buf_read_ahead_random(...){ ...
       if (srv_startup_is_before_trx_rollback_phase) {
                /* No read-ahead to avoid thread deadlocks */
                return(0);
        }
</pre>
<p>This variable is tested at two functions &#8211; buf_read_ahead_linear() and buf_read_ahead_random() and <b>nowhere else</b>. So yeah, &#8220;server startup is before transaction rollback phase&#8221; is another way of saying &#8220;don&#8217;t do read ahead, please please&#8221;. </p>
<pre>gdb -ex "set  srv_startup_is_before_trx_rollback_phase=1" \
    --batch -p $(pidof mysqld)</pre>
<p>And many servers bottlenecked on this became much much much faster (and 2000 concurrent threads running dropped to 10). Of course, this is most visible in high-latency-high-throughput I/O situations, but we&#8217;re hitting this contention spot on local disk setups too. </p>
<p>Don&#8217;t forget to have <a href='http://mituzas.lt/2009/12/29/when-bad-things-happen/'>the fix</a> if gdb decides to be nasty and locks up your server :)</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2010/01/02/read-ahead/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>When bad things happen!</title>
		<link>http://mituzas.lt/2009/12/29/when-bad-things-happen/</link>
		<comments>http://mituzas.lt/2009/12/29/when-bad-things-happen/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 16:25:23 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[gdb]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=715</guid>
		<description><![CDATA[When bad things happen, like&#8230; &#8217;strace -f&#8217; or &#8216;gdb&#8217; or any other process inspection tool decides to hang your precious processes (they show up in state T in process lists), there&#8217;s always help:

#include &#60;sys/ptrace.h&#62;
#include &#60;signal.h&#62;
main(int ac, char **av) {
int pid; if (ac&#62;1) pid=atoi(av[1]);
ptrace(PTRACE_ATTACH,pid,0,0);
ptrace(PTRACE_DETACH,pid,0,0);
kill(pid, SIGCONT); }

]]></description>
			<content:encoded><![CDATA[<p>When bad things happen, like&#8230; &#8217;strace -f&#8217; or &#8216;gdb&#8217; or any other process inspection tool decides to hang your precious processes (they show up in state T in process lists), there&#8217;s always help:</p>
<pre>
#include &lt;sys/ptrace.h&gt;
#include &lt;signal.h&gt;
main(int ac, char **av) {
int pid; if (ac&gt;1) pid=atoi(av[1]);
ptrace(PTRACE_ATTACH,pid,0,0);
ptrace(PTRACE_DETACH,pid,0,0);
kill(pid, SIGCONT); }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/12/29/when-bad-things-happen/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PMP!</title>
		<link>http://mituzas.lt/2009/12/27/pmp/</link>
		<comments>http://mituzas.lt/2009/12/27/pmp/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 18:55:58 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[profiling]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=709</guid>
		<description><![CDATA[It is a glorious day today &#8211; Poor Man&#8217;s Profiler (previously introduced here) just got its own website. Do visit it at http://poormansprofiler.org/ &#8211; and contribute to better tomorrow. 
]]></description>
			<content:encoded><![CDATA[<p>It is a glorious day today &#8211; Poor Man&#8217;s Profiler (previously introduced <a href="http://mituzas.lt/2009/02/15/poor-mans-contention-profiling/">here</a>) just got its own website. Do visit it at <a href="http://poormansprofiler.org/">http://poormansprofiler.org/</a> &#8211; and contribute to better tomorrow. </p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/12/27/pmp/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Opening tables!</title>
		<link>http://mituzas.lt/2009/12/26/opening-tables/</link>
		<comments>http://mituzas.lt/2009/12/26/opening-tables/#comments</comments>
		<pubDate>Fri, 25 Dec 2009 22:30:46 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[innodb]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=702</guid>
		<description><![CDATA[There&#8217;s one bottleneck in MySQL/InnoDB that ultimately sucks. It sucked in 4.0, sucked in 5.0, sucks in 5.1 with newest InnoDB plugin. Opening tables has been a bottleneck on machines that have thousands of tables all the time (as LOCK_open is being held during the process), and while there was a table being opened, everything [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s one bottleneck in MySQL/InnoDB that ultimately sucks. It sucked in 4.0, sucked in 5.0, sucks in 5.1 with newest InnoDB plugin. Opening tables has been a bottleneck on machines that have thousands of tables all the time (as LOCK_open is being held during the process), and while there was a table being opened, everything else would stall on the machine. </p>
<p>It can simply take hours on such systems just to open tables &#8211; and the major portion of time spent is randomly diving into InnoDB tables to populate index statistics. It obviously sounds like low hanging fruit &#8211; as statistics aren&#8217;t needed while you are opening a table, they&#8217;re needed just for querying the table. </p>
<p>So, I threw in few thousand tables to my machine, and tried opening them with ten connections. Standard InnoDB code was opening 13.5 tables a second. After spending few minutes and <a href="http://p.defau.lt/?7z_wf6C9Xk0b0XFyD9AaeA">moving</a> (this is pure prototype, not suitable for production) statistic collection post ha_innodb::open(), I noticed performance increase.</p>
<p>Tables were opened at 105-a-second speed. A bit better, ~8x better. </p>
<p>Merry Christmas, MySQL!</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/12/26/opening-tables/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>On deadlock detection</title>
		<link>http://mituzas.lt/2009/12/21/on-deadlock-detection/</link>
		<comments>http://mituzas.lt/2009/12/21/on-deadlock-detection/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 22:41:21 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[innodb]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=698</guid>
		<description><![CDATA[InnoDB detects deadlocks. Deadlocks are those nasty situations, when transaction 1 tries to acquire locks A and B, whereas transaction 2 tries to acquire locks B and A at the same time. As both are stubborn, InnoDB will decide simply to terminate one of them. If it wouldn&#8217;t do that, both transactions would have to [...]]]></description>
			<content:encoded><![CDATA[<p>InnoDB detects deadlocks. Deadlocks are those nasty situations, when transaction 1 tries to acquire locks A and B, whereas transaction 2 tries to acquire locks B and A at the same time. As both are stubborn, InnoDB will decide simply to terminate one of them. If it wouldn&#8217;t do that, both transactions would have to wait until lock_wait_timeout to expire otherwise. There is a big chance that longer the transaction is, more likely it is to cause deadlocks. Deadlock detection kind of helps, then, but&#8230; at certain costs.</p>
<p>Transaction 1 and 2 case is way too easy, try adding few hundred transactions that contend over same set of locks. To do that, InnoDB deadlock monitor will recursively brute-force lock graph, until it hits a 200-transaction-long chain (it will say it is a deadlock), or until it runs out of paths to check. Still, with the power of modern hardware that will still be milliseconds.</p>
<p>Unfortunately, InnoDB will also hold kernel_mutex at that time, so lots and lots of InnoDB operations will not happen at that time. To be exact, InnoDB will rarely do anything else, while deadlock check is happening.</p>
<p>To illustrate that, I have a very simple testcase (that in certain conditions stalls the server for half an hour, even if it is not being ran):</p>
<blockquote><p>UPDATE t1 SET b=b+1 WHERE a=1;</p></blockquote>
<p>With few threads it executes nearly 20000 times a second on my desktop machine. With ten threads it executes 14000/s. With 50 threads it is only 3000/s. With 100 threads it falls down to 639 operations a second. At 140 threads it is already just 266.</p>
<p>I built InnoDB without deadlock detection (<a href="http://p.defau.lt/?GF5_toN1gdzdFQCLK1Dg_w">tiny tiny patch</a>), and tried same test. Similar performance with 10 threads, still doing 10000 operations a second at 100 threads:<br />
<img src="http://spreadsheets.google.com/oimg?key=0AtHDNfVx0WNhdDA3dmtjOVItZHFKZjRGMFBpd0JUaUE&#038;oid=1&#038;v=1261348373043" /></p>
<p>Though I illustrated edge case here, its purity actually didn&#8217;t show how bad this can go &#8211; this situation can happen not only because of high contention on single row, but simply because someone holds up the row lock for a bit too long (there&#8217;s always that sleep between UPDATE and COMMIT, too). It can take a single transaction to cause a lock convoy, and once transactions queue up, and update rate falls down below 100/s, all MySQL will be doing is checking for deadlocks, even if they never happen. </p>
<p>On many systems deadlock detection is causing way more issues, than lack of it would. Most deadlocks happen on transactions that are somewhere in the middle of their lock wait anyway :) </p>
<p>There&#8217;s some discussion about it at MySQL <a href="http://bugs.mysql.com/bug.php?id=49047">Bug#49047</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/12/21/on-deadlock-detection/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>On replication, some more</title>
		<link>http://mituzas.lt/2009/12/13/on-replication-some-more/</link>
		<comments>http://mituzas.lt/2009/12/13/on-replication-some-more/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 17:24:24 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=679</guid>
		<description><![CDATA[Dear MySQL,
I feel ashamed that I ever wanted you to support 4.0-&#62;5.1 replication, and apologize for that. I really understand that it was really egoistic of me even to consider you should be involved in this.
I even understand that 5.0 is running out of active support (I&#8217;m not questioning that you&#8217;ll stop supporting 4.1 entirely [...]]]></description>
			<content:encoded><![CDATA[<p>Dear MySQL,</p>
<p>I feel ashamed that I ever <a href="http://bugs.mysql.com/bug.php?id=49474">wanted</a> you to<a href="http://bugs.mysql.com/bug.php?id=48369"> support 4.0-&gt;5.1 replication</a>, and apologize for <a href="http://mituzas.lt/2009/12/05/on-replication-compatibility/">that</a>. I really understand that it was really egoistic of me even to consider you should be involved in this.</p>
<p>I even understand that 5.0 is running out of <a href="http://www.mysql.com/about/legal/lifecycle/">active support</a> (I&#8217;m not questioning that you&#8217;ll stop supporting 4.1 entirely too), and you&#8217;ll stop doing pretty much anything to 5.0, except &#8220;critical security fixes&#8221; (w00t, I managed to <a href="http://bugs.mysql.com/bug.php?id=47320">get one</a> into 4.1, 8 year old MITM flaw :).</p>
<p>I really understand that supporting more than one release is very very very difficult, and people should do only adjacent version upgrade.</p>
<p>I&#8217;m not asking you much, but, maybe you could then support 5.1 to 5.1 replication? I don&#8217;t want much, just:</p>
<ul>
<li>Gracefully recover after slave crashes.</li>
<li>Don&#8217;t have single serial reading of pages for replication stream as a bottleneck &#8211; either read-ahead properly (you can do that with RBR!!!), or apply events in parallel (you can do that with RBR too!)</li>
<li>Allow to edit replication filters without restarting servers.</li>
<li>Allow to enable and disable binary logging of events received from master, as well as enabling and disabling binary logging without restarting the instance.</li>
</ul>
<p>I hope it isn&#8217;t too much too ask! It is just supported replication between two same version instances.</p>
<p>Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/12/13/on-replication-some-more/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>best free() is exit()</title>
		<link>http://mituzas.lt/2009/12/10/best-free-is-exit/</link>
		<comments>http://mituzas.lt/2009/12/10/best-free-is-exit/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 15:50:09 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=674</guid>
		<description><![CDATA[Whenever any maintenance needs server restarts, there&#8217;s a list of unsolved bottlenecks or inefficient code that gets touched a lot at that time. I can understand that heating up the server can take lots of time (though lots of low hanging fruits there), but the way actual shutdown is done, even if there&#8217;s not much [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever any maintenance needs server restarts, there&#8217;s a list of unsolved bottlenecks or inefficient code that gets touched a lot at that time. I can understand that heating up the server can take lots of time (though lots of low hanging fruits there), but the way actual shutdown is done, even if there&#8217;s not much of dirty data to flush, sucks.</p>
<p>See, developers are perfectionists, and their perfectionism also includes the crazy idea that all memory has to be deallocated at server shutdown, as otherwise Valgrind and other tools will complain that someone leaked memory. Developers will write expensive code in shutdown routines that will traverse every memory structure and deallocate/free() it. </p>
<p>Now, guess what would happen if they wouldn&#8217;t write all this expensive memory deallocation code.</p>
<p>Still guessing?</p>
<p>OS would do it for them, much much much faster, without blocking the shutdown for minutes or using excessive amounts of CPU. \o/</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/12/10/best-free-is-exit/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Crash recovery, again</title>
		<link>http://mituzas.lt/2009/12/08/crash-recovery-again/</link>
		<comments>http://mituzas.lt/2009/12/08/crash-recovery-again/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 13:29:30 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[crash]]></category>
		<category><![CDATA[innodb]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=658</guid>
		<description><![CDATA[There&#8217;s one stage in InnoDB crash recovery where it reads log file, you know, this one:

InnoDB: Doing recovery: scanned up to log sequence number 354164119040
InnoDB: Doing recovery: scanned up to log sequence number 354169361920

 On a machine with bigger logs it will start spending nearly 100% CPU somewhere in recv_scan_log_recs. Guess what it does&#8230;. -fno-inline [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s one stage in InnoDB crash recovery where it reads log file, you know, this one:</p>
<pre>
InnoDB: Doing recovery: scanned up to log sequence number 354164119040
InnoDB: Doing recovery: scanned up to log sequence number 354169361920
</pre>
<p> On a machine with bigger logs it will start spending nearly 100% CPU somewhere in <em>recv_scan_log_recs</em>. Guess what it does&#8230;. -fno-inline builds to the rescue:</p>
<pre>
#0  mem_block_get_len at ./include/mem0mem.ic:86
#1  mem_heap_get_size at ./include/mem0mem.ic:591
#2  recv_scan_log_recs at log/log0recv.c:2727
</pre>
<p>And:</p>
<pre>
samples  %        symbol name
8467     72.9222  mem_heap_get_size
291       2.5062  recv_add_to_hash_table
95        0.8182  mem_block_get_len
</pre>
<p>To speak in layman&#8217;s terms, InnoDB does SUM(LENGTH(allocation)) on its relatively wide memory (tens, hundreds of thousands of entries) arena, FOR EVERY LOG SEGMENT, to make sure it didn&#8217;t run out of available 32GBs. Hehehe, lame. </p>
<p>As for now, I&#8217;ll just <a href='http://p.defau.lt/?xHI2A_wc1pwyYvNNx_SbWA'>killed</a> the check and have my recovery much much faster &#8211; finished in 3 minutes, what it wasn&#8217;t able to do in 30 before. </p>
<p>P.S. This is different from what I <a href='http://mituzas.lt/2008/10/26/innodb-crash-recovery/'>wrote before</a> (and magic Yasufumi&#8217;s patch)<br />
P.P.S. Now I got to learn to reuse LOG_DUMMY table during the recovery process, as it is next low hanging fruit there&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/12/08/crash-recovery-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>on replication compatibility</title>
		<link>http://mituzas.lt/2009/12/05/on-replication-compatibility/</link>
		<comments>http://mituzas.lt/2009/12/05/on-replication-compatibility/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 21:45:44 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[fork]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=652</guid>
		<description><![CDATA[Dear MySQL,
I will do this to rest of your code, if you continue breaking replication for me.
&#8211; Domas
]]></description>
			<content:encoded><![CDATA[<p>Dear MySQL,</p>
<p>I will do <a href="http://bazaar.launchpad.net/%7Ewikimedia/sakila-server/mysql-5.1-wm/revision/3191">this</a> to rest of your code, if you continue <a href="http://bugs.mysql.com/bug.php?id=49474">breaking replication</a> for me.</p>
<p>&#8211; Domas</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/12/05/on-replication-compatibility/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>again, on benchmarks</title>
		<link>http://mituzas.lt/2009/11/19/again-on-benchmarks/</link>
		<comments>http://mituzas.lt/2009/11/19/again-on-benchmarks/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 18:03:34 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=645</guid>
		<description><![CDATA[Dear interweb, if you have no idea what you&#8217;re writing about, keep it to yourself, don&#8217;t litter into the tubes. Some people may not notice they&#8217;re eating absolute crap and get diarrhea.
This particular benchmark has two favorite parts, that go with each other together really well:
I didnt change absolutely any parameters for the servers, eg [...]]]></description>
			<content:encoded><![CDATA[<p>Dear interweb, if you have <a href="http://www.ruturaj.net/redis-memcached-tokyo-tyrant-mysql-comparison">no idea</a> what you&#8217;re writing about, keep it to yourself, don&#8217;t litter into the tubes. Some people may not notice they&#8217;re eating absolute crap and get diarrhea.</p>
<p>This particular benchmark has two favorite parts, that go with each other together really well:</p>
<p style="padding-left: 30px;">I didnt change absolutely any parameters for the servers, eg didn&#8217;t change the innodb_buffer_pool_size or key_buffer_size.</p>
<p>And..</p>
<p style="padding-left: 30px;">If you need speed just to fetch a data for a given combination or key, Redis is a solution that you need to look at. MySQL can no way compare to Redis and Memcache. &#8230;</p>
<p>Seriously, how does one repay for all the damage of such idiotic benchmarks?</p>
<p>P.S. I&#8217;ve <a href="http://mituzas.lt/2009/06/30/on-file-system-benchmarks/">ranted</a> at benchmarks before, and will continue doing so.</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/11/19/again-on-benchmarks/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>update</title>
		<link>http://mituzas.lt/2009/11/18/update/</link>
		<comments>http://mituzas.lt/2009/11/18/update/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 18:36:46 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[wikitech]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=641</guid>
		<description><![CDATA[In past few months I had lots of changes going on &#8211; left the Sun/MySQL job, my term on Wikimedia Board of Trustees ended, I joined Facebook and now I got appointed to Wikimedia Advisory Board. This also probably means that I will have slightly less hands-on work on Wikipedia technology (I&#8217;ll be mostly in [...]]]></description>
			<content:encoded><![CDATA[<p>In past few months I had lots of changes going on &#8211; left the Sun/MySQL job, my term on Wikimedia Board of Trustees ended, I joined Facebook and now I <a href="http://lists.wikimedia.org/pipermail/foundation-l/2009-November/056031.html">got appointed</a> to Wikimedia <a href="http://wikimediafoundation.org/wiki/Advisory_Board">Advisory Board</a>. This also probably means that I will have slightly less hands-on work on Wikipedia technology (I&#8217;ll be mostly in &#8220;r<em>elaxed maintenance mode</em>&#8220;), though I don&#8217;t know yet how much less &#8211; time will show :)</p>
<p><span style="color: #c0c0c0;">P.S. I also quit World of Warcraft. ;-) </span></p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/11/18/update/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A formal objection to formal objection!</title>
		<link>http://mituzas.lt/2009/11/11/a-formal-objection-to-formal-objection/</link>
		<comments>http://mituzas.lt/2009/11/11/a-formal-objection-to-formal-objection/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 01:08:53 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[ec]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=639</guid>
		<description><![CDATA[Dear EC, I have an opinion on Sun/Oracle merger.
I don&#8217;t like objections, therefore I object to them. Of course, I understand, that some people want to play major parts in dramas and soap operas, others are spectating and enjoying it, but most people I know and respect simply want to be efficient and get their [...]]]></description>
			<content:encoded><![CDATA[<p>Dear EC, I have an opinion on Sun/Oracle merger.</p>
<p>I don&#8217;t like objections, therefore I object to them. Of course, I understand, that some people want to play major parts in dramas and soap operas, others are spectating and enjoying it, but most people I know and respect simply want to be efficient and get their work done.</p>
<p>These people, many of whom were my colleagues back at Sun/MySQL, sometimes can be labeled as ones who don&#8217;t care about greater picture, or the common good. Unfortunately, the topic of common interest depends from religion to religion, from society to society, from person to person.</p>
<p>My approach to common good is doing what I want to do for the community, and not what community wants me to do. If that relation is not compatible for any of the sides, there is no relation at all. Now, what happens now, is that there is some user community (and I include all the people who are protecting their free-software-usage interests) which has demands for vendors.</p>
<p>When PG zealots keep telling that &#8220;PG is open, MySQL is closed-development by a company&#8221;, you will often see MySQL camp not listening to that at all. But there is some true in that, every MySQL user was using a product that was developed inside a citadel (even some builds were called &#8216;Citadel&#8217;), and company had a say over lots of issues.</p>
<p>Start with Windows licensing at the beginning, GPLv2 versus GPLv3 or any other issue, that was affecting our user community at large, it has always been top-down decision, nobody has ever asked me as a user what kind of license I would want &#8211; and all those decisions were made by MySQL, the semi-independent company.</p>
<p>I never actually craved for too much control of the project &#8211; I&#8217;m always free to fork (and I have forked at least 3 releases of MySQL, and now have to deal with yet another fork at work ;-). I have went through various stages of relations with MySQL &#8211; and at every of them I had to understand that open-source software carries its own set of risks, but also has its own set of mitigations. I&#8217;m free to support my organization needs at various outcomes, I don&#8217;t have any data lock-in, I don&#8217;t have any vendor lock-in, the only impact is a risk that I should have calculated years ago, not today.</p>
<p>So even if the argument starts with &#8220;MySQL is being acquired by competitor, and it is risky situation&#8221;, there are few real messages out there: &#8220;we need to protect people who don&#8217;t care about risks&#8221; &#8211; sounds very much like bailout money for all the people with crazy spending, as well as &#8220;if your entry campaign is about doing lots of common good, you may not be allowed to profit in the future&#8221;.</p>
<p>This doesn&#8217;t make open-source a good investment (would Sun pay 1B$ if it forecasted today&#8217;s EC position?), and it not being a good investment means there won&#8217;t be opportunities for people to balance common good and business opportunities in future.</p>
<p>If a community was supposed to have a voice in this situation, it should&#8217;ve had a fair share of board members in project management. If a community didn&#8217;t get its fair share of management at the organization, it should&#8217;ve found another organization, or accepted the risks.</p>
<p>In my opinion, if you are right now in the camp of supporting objections, it is not because you&#8217;re seeing a lot now, it is mostly because you didn&#8217;t see anything before.</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/11/11/a-formal-objection-to-formal-objection/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>GDB 7!</title>
		<link>http://mituzas.lt/2009/10/08/gdb-7/</link>
		<comments>http://mituzas.lt/2009/10/08/gdb-7/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 20:30:39 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[wikitech]]></category>
		<category><![CDATA[gdb]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=630</guid>
		<description><![CDATA[I wasn&#8217;t prepared for this. After spending months playing with GDB development trees I somehow entirely missed that 7.0 release is getting close, and took me more than an hour to spot it.
My favorite features are python scripting and non-stop debugging. I was toying around with python scripting for a while, and was planning to [...]]]></description>
			<content:encoded><![CDATA[<p>I wasn&#8217;t prepared for this. After spending months playing with GDB development trees I somehow entirely missed that <a href="http://www.gnu.org/software/gdb/download/ANNOUNCEMENT">7.0 release</a> is getting close, and took me more than an hour to spot it.</p>
<p>My favorite features are python scripting and non-stop debugging. I was toying around with python scripting for a while, and was planning to make backtraces make sense. Having hands that open means that one can see PHP backtraces, when gdb&#8217;ing apache, see table names and states when MySQL thread access handler interfaces, or remote IPs and users, when it is writing to network. Process inspection can simply rock, if right tools are created using these new capabilities, and I&#8217;m way too excited when I think about those. &#8220;Always have debugging symbols&#8221; gets way more meaning now.</p>
<p>Another issue I&#8217;ve been trying to resolve lately is avoiding long locking periods for running processes (directly attaching to process can freeze its work for a second or so, which isn&#8217;t that tolerable in production environments). GDB is getting closer to the async debugging capabilities &#8211; where one can run a debugger without actually stopping anything.</p>
<p>So, congratulations GDB team, now it is job for us to find all the uses of the tool. It has been invaluable so far, but this is much much more.</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/10/08/gdb-7/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL processlist phrase book</title>
		<link>http://mituzas.lt/2009/09/27/mysql-processlist-phrase-book/</link>
		<comments>http://mituzas.lt/2009/09/27/mysql-processlist-phrase-book/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 09:11:04 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=620</guid>
		<description><![CDATA[For your convenience, a short phrase book, starting with explanation of process states where MySQL is mostly working to look up data from tables:

&#8220;Sending data&#8221; &#8211; reading data from tables (or looking it up)
&#8220;Copying to tmp table&#8221; &#8211; reading data from tables (or looking it up)
&#8220;Copying to tmp table on disk&#8221; &#8211; query needs a [...]]]></description>
			<content:encoded><![CDATA[<p>For your convenience, a short phrase book, starting with explanation of process states where MySQL is mostly working to look up data from tables:</p>
<ul>
<li>&#8220;Sending data&#8221; &#8211; reading data from tables (or looking it up)</li>
<li>&#8220;Copying to tmp table&#8221; &#8211; reading data from tables (or looking it up)</li>
<li>&#8220;Copying to tmp table on disk&#8221; &#8211; query needs a rewrite</li>
<li>&#8220;statistics&#8221; &#8211; looking up data from tables</li>
<li>&#8220;Sorting result&#8221; &#8211; reading data from tables (or looking it up)</li>
</ul>
<p>Locking is fun:</p>
<ul>
<li>&#8220;update&#8221; &#8211; There is big chance that it is waiting for a lock, can be updating as well, on busy systems</li>
<li>&#8220;Locked&#8221; &#8211; Even bigger chance that it is MyISAM table waiting to be converted to InnoDB</li>
</ul>
<p>Table opening is even funnier:</p>
<ul>
<li>&#8220;Opening tables&#8221; &#8211; some other idiot thread is holding the LOCK_open or similar mutex</li>
<li>&#8220;Closing tables&#8221; &#8211; some other idiot thread is holding the LOCK_open or similar mutex</li>
<li>&#8220;Opening table&#8221; &#8211; the idiot thread (or not that smart DBA who thinks that table_cache should be set to current value)</li>
<li>&#8220;Flushing tables&#8221; &#8211; someone decided that flushing tables is good idea, but forgot to kill long running queries</li>
<li>&#8220;Waiting for tables&#8221; &#8211; same as &#8220;Flushing tables&#8221;</li>
</ul>
<p>If you have replication:</p>
<ul>
<li>&#8220;Connecting to server&#8221; &#8211; could not connect to server, waiting to retry</li>
<li>&#8220;Reconnecting after a failed master event read&#8221; &#8211; master and slave have same @server_id</li>
<li>&#8220;Registering slave on master&#8221; &#8211; master and slave have same @server_id</li>
<li>&#8220;Waiting to reconnect after a failed master event read&#8221; &#8211; master and slave have same @server_id</li>
</ul>
<p>Few more tricky ones:</p>
<ul>
<li>&#8220;Sleep&#8221; &#8211; last millisecond it was probably not sleeping, due to how process scheduling and kernel level buffering works probably it has finished right before kernel switched to the &#8216;SHOW PROCESSLIST&#8217; thread.</li>
<li>&#8220;Writing to net&#8221; &#8211; usually, <span style="text-decoration: underline;">not</span> writing to net (client has blocked) &#8211; actual writing to net is usually nearly non-blocking operation, as long as client doesn&#8217;t sleep.</li>
<li>&#8220;Killed&#8221; &#8211; actually, someone tried to kill it, but it doesn&#8217;t care, as it doesn&#8217;t check for thd-&gt;killed flag</li>
</ul>
<p>And in the user column:</p>
<ul>
<li>&#8220;unauthenticated user&#8221; &#8211; are you sure your DNS is working right?</li>
<li>&#8220;system user&#8221; &#8211; it isn&#8217;t user, these are (hopefully plural) replication threads, that don&#8217;t have any &#8220;user&#8221; credentials</li>
<li>&#8220;root&#8221; &#8211; either that is you running the PROCESSLIST, another session you forgot you are running or you forgot to create separate user for your application</li>
</ul>
<p>I probably didn&#8217;t write quite a few important ones, but some of them are self-evident (such as &#8220;init&#8221; and &#8220;end&#8221;), and others probably will never show up :)</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/09/27/mysql-processlist-phrase-book/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Getting apache core dumps in Linux</title>
		<link>http://mituzas.lt/2009/09/26/getting-apache-core-dumps-in-linux/</link>
		<comments>http://mituzas.lt/2009/09/26/getting-apache-core-dumps-in-linux/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 18:24:48 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=616</guid>
		<description><![CDATA[If you want to get core dumps for intermittent Apache/mod_php crashes in Linux, you will probably need this module (otherwise Linux kernel will refuse to dump core, whatever you put into your OS or Apache configuration):

/*
* Author: Domas Mituzas
* Released to public domain
*
* apxs -c -i mod_dumpcore.c
* and...
* LoadModule dumpcore_module .../path/to/mod_dumpcore.c
* CoreDumpDirectory /tmp/cores/
* and...
* sysctl [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to get core dumps for intermittent Apache/mod_php crashes in Linux, you will probably need this module (otherwise Linux kernel will refuse to dump core, whatever you put into your OS or Apache configuration):</p>
<p><code><br />
/*<br />
* Author: Domas Mituzas<br />
* Released to public domain<br />
*<br />
* apxs -c -i mod_dumpcore.c<br />
* and...<br />
* LoadModule dumpcore_module .../path/to/mod_dumpcore.c<br />
* CoreDumpDirectory /tmp/cores/<br />
* and...<br />
* sysctl -w kernel.core_pattern=/tmp/cores/core.%p.%t<br />
*/</code></p>
<p><code> </code></p>
<p><code>#include "httpd.h"<br />
#include "http_config.h"<br />
#include &lt;sys/prctl.h&gt;</code></p>
<p><code>static int dumpcore_handler(request_rec *r)<br />
{ prctl(PR_SET_DUMPABLE,1,0,0,0); return DECLINED; }</p>
<p>static void dumpcore_register_hooks(apr_pool_t *p)<br />
{ap_hook_handler(dumpcore_handler, NULL, NULL, APR_HOOK_MIDDLE);}</p>
<p></code></p>
<p><code>module AP_MODULE_DECLARE_DATA dumpcore_module = {<br />
STANDARD20_MODULE_STUFF, NULL, NULL, NULL, NULL, NULL,<br />
dumpcore_register_hooks };<br />
</code></p>
<p>P.S. I was quite astonished to find out that nobody ever needed this, I remember quite a few discussions after which we fixed this in MySQL <a href="http://bugs.mysql.com/bug.php?id=21723">two years ago</a>.</p>
<p><strong>Update: </strong>there&#8217;s also &#8216;echo 1 &gt; /proc/sys/fs/suid_dumpable&#8217; or &#8217;sysctl -w fs.suid_dumpable=1&#8242; &#8211; now I recall whole story, RHEL3 and RHEL4 didn&#8217;t have this, so we had to do prctl() hack, whereas later Linux kernel versions allowed this workaround.</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/09/26/getting-apache-core-dumps-in-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dear IT Security Industry&#8230;</title>
		<link>http://mituzas.lt/2009/09/10/security-industry-crap/</link>
		<comments>http://mituzas.lt/2009/09/10/security-industry-crap/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 21:59:19 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=597</guid>
		<description><![CDATA[&#8230; You are full of shit.
I don&#8217;t know how effective your scare-mongering cash-extortion tactics are, but they don&#8217;t really help neither your users, nor vendors, nor anyone else.
It all starts when major vulnerability databases start authoritatively spouting out crap like this:
A vulnerability has been reported in MySQL, which can be exploited to compromise a vulnerable [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230; You are full of shit.</p>
<p>I don&#8217;t know how effective your scare-mongering cash-extortion tactics are, but they don&#8217;t really help neither your users, nor vendors, nor anyone else.</p>
<p>It all starts when major vulnerability databases start authoritatively spouting out crap like this:</p>
<p style="padding-left: 30px; ">A vulnerability has been reported in MySQL, which can be exploited to compromise a vulnerable system.<br />
The vulnerability is caused due to an unspecified error and can be exploited to cause a buffer overflow. (<a href="http://secunia.com/advisories/36575/">Secunia</a>)</p>
<p>Or crap like this:
</p>
<p style="padding-left: 30px; ">MySQL is prone to a buffer-overflow vulnerability because if fails to perform adequate boundary checks on user-supplied data.<br />
An attacker can leverage this issue to execute arbitrary code within the context of the vulnerable application. Failed exploit attempts will result in a denial-of-service condition. (<a href="http://www.securityfocus.com/bid/36242/discuss">Securityfocus</a>)</p>
<p><span id="more-597"></span></p>
<p>Of course, there must be some reason to publish such claims, right? Of course, if you brought in cash for all these security vendors, they&#8217;d definitely tell you that in future they will give you all available updates, but for now:
</p>
<p style="padding-left: 30px; ">Due to the very limited available information, it is not possible to suggest an effective workaround.</p>
<p>Why would one post such crap? Because people want to sell things, like vulnerability databases full of rubbish:</p>
<p style="padding-left: 30px; ">A working commercial exploit is available through Intevydis. This exploit is not otherwise publicly available or known to be circulating in the wild (<a href="http://www.securityfocus.com/bid/36242/exploit">Securityfocus</a>)</p>
<p>This is how the Security Vendor that unleashed this all classifies the vulnerability:</p>
<ul>
<li><strong>Name</strong>: MySQL 5.x exploit</li>
<li><strong>Status</strong>: 0day</li>
<li><strong>Details</strong>: Remote buffer overflow exploit. Tested on Debian Linux 5.0 with mysql-server 5.0.51a-24+lenny1</li>
<li><strong>Listener</strong>: LINUXMOSDEF</li>
<li><strong>Platform</strong>: Linux x86</li>
</ul>
<p>If you&#8217;d look it up, Debian just had security advisory <a href="http://www.debian.org/security/2009/dsa-1877">DSA-1877-1</a> (released at September 2nd, one day before Secunia and Securityfocus went live with their stuff), which tells us about denial of service and execution of arbitrary code possibility. The +lenny2 package fixes it, the +lenny1 package is vulnerable. At this point, I don&#8217;t really have anything against Debian security people &#8211; Linux distribution security contacts are always eager to communicate, share, discuss, and, well, admit failures &#8211; and as they are not in money extortion business, it is very easy to forgive them. Still, the advisory mentions &#8220;potential execution of arbitrary code via format string specifiers&#8221;. See, original exploit at <a href="http://www.milw0rm.com/exploits/9085">milw0rm</a> did mention &#8220;format string vulnerability&#8221;, which is source of  [easily understandable] confusion here.</p>
<p>Various C libraries allow passing %n format specifier to printf() calls, which is:</p>
<p style="padding-left: 30px; ">The number of characters written so far is stored into the integer indicated by the int * (or variant) pointer argument.  No argument is converted.</p>
<p>This means that if you allow someone to pass a format string, he can overwrite memory of your application with specially crafted data (though, it isn&#8217;t that trivial to exploit it). MySQL though, as it has to be very portable, has its own version of printf, to avoid any OS-specific behaviors, and that implementation does not have %n, which means by passing arbitrary format string you cannot execute arbitrary code. Phew.</p>
<p>So, what is the bug? Let me present you <a href="http://bugs.mysql.com/bug.php?id=45790">Bug#45790</a>:</p>
<ul>
<li>If server has General Query Log enabled (thats very very low percentage of systems out there) and&#8230;.</li>
<li>User has right to create databases (which isn&#8217;t a right given away to every user out there&#8230;.) then&#8230;</li>
<li>He can shut down (well, crash) the server!</li>
</ul>
<p>Summary of this whole security catastrophe in practice would be:</p>
<p style="padding-left: 30px;">System administrator can shut down MySQL server</p>
<p>My heart pounds and I hurry to upgrade every machine to 5.0.84 (sarcasm aside, do it anyway, it has great fixes ;-).</p>
<p>P.S. I may be wrong, and there is an exploit which will convert your database clusters into botnet zombies, capable of much more than regular botnets &#8211; imagine all the multicore servers attached to SANs completely dominating the world. Scary. Thats why we try to work on all security threats &#8211; even if it takes quite a few hours too long for what it deserves.</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/09/10/security-industry-crap/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Spikes are not fun anymore</title>
		<link>http://mituzas.lt/2009/08/20/spikes-are-not-fun-anymore/</link>
		<comments>http://mituzas.lt/2009/08/20/spikes-are-not-fun-anymore/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 07:46:38 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[wikipedia]]></category>
		<category><![CDATA[wikitech]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=585</guid>
		<description><![CDATA[English Wikipedia just scored &#8220;three million articles&#8221;, so I thought I&#8217;d give some more numbers and perspectives :) Four years ago we observed impressive +50% traffic spike on Wikipedia &#8211; people came in to read about the new pope. Back then it was probably twenty additional page views a second, and we were quite happy [...]]]></description>
			<content:encoded><![CDATA[<p>English Wikipedia just scored &#8220;three million articles&#8221;, so I thought I&#8217;d give some more numbers and perspectives :) Four years ago we observed impressive +50% traffic spike on Wikipedia &#8211; people came in to read about the <a href="http://midom.livejournal.com/1364.html">new pope</a>. Back then it was probably twenty additional page views a second, and we were quite happy to sustain that additional load :)</p>
<p>Nowadays big media events can cause <a href="http://mituzas.lt/2009/06/26/embarrassment/">some troubles</a>, but generally they don&#8217;t bring huge traffic spikes anymore. Say, Michael Jackson&#8217;s English Wikipedia article had peak hour of one million page views (2009-06-25 23:00-24:00) &#8211; and that was merely 10% increase on one of our projects (English Wikipedia got 10.4m pageviews that hour). Our problems back then were caused by complexity of page content &#8211; and costs got inflated because of lack of rendering farm concurrency control.</p>
<p>Other interesting sources of attention are custom Google logos leading to search results leading to Wikipedia (of course!). Last ones, for <a href="http://en.wikipedia.org/wiki/Perseids">Perseids</a> or <a href="http://en.wikipedia.org/wiki/Hans_Christian_Ørsted">Hans Christian Ørsted</a> sent over 1.5m daily visitors each &#8211; but thats mere 20 article views a second or so.</p>
<p>What makes those spikes boring nowadays is simply the length of long-tail. Our projects serve over five million <em>different</em> articles over the course of an hour (and 20m article views) &#8211; around 3.5m articles are opened just once. If our job would be serving just hot news, our cluster setup and software infrastructure would be very very very different &#8211; and now we have to accommodate millions of articles, that aren&#8217;t just stored in archives, but also are constantly read, even if once an hour (and daily hot set is much larger too).</p>
<p>All this viewership data is available in <a href="http://dammit.lt/wikistats/">raw form</a>, as well as nice visualizations at <a href="http://www.trendingtopics.org/">trendingtopics</a>, <a href="http://wikirank.com/en">wikirank</a> and <a href="http://stats.grok.se/">stats.grok.se</a>. It is amazing to hear about all the research that is built on this kind of data, and I guess it needs some improved interfaces and APIs already for all the future uses ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/08/20/spikes-are-not-fun-anymore/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>plugin and 5.1</title>
		<link>http://mituzas.lt/2009/08/18/plugin-and-5-1/</link>
		<comments>http://mituzas.lt/2009/08/18/plugin-and-5-1/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 08:50:54 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[innodb]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=582</guid>
		<description><![CDATA[You can check it yourself &#8211; 5.1 seems to be shipped with InnoDB plugin in future :-) (oh the joy of open source repositories, always ready to spoil the surprise, eh?:)
]]></description>
			<content:encoded><![CDATA[<p>You can check it <a href="http://bazaar.launchpad.net/~mysql/mysql-server/mysql-5.1/revision/2963">yourself</a> &#8211; 5.1 seems to be shipped with InnoDB plugin in future :-) (oh the joy of open source repositories, always ready to spoil the surprise, eh?:)</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/08/18/plugin-and-5-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL DBA, python edition</title>
		<link>http://mituzas.lt/2009/08/17/dba-python-scripts/</link>
		<comments>http://mituzas.lt/2009/08/17/dba-python-scripts/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 08:08:29 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[dba]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=579</guid>
		<description><![CDATA[In the age of jetsetting and space travel and ORMs and such, MySQL DBAs are the least sophisticated ones nowadays, usually fighting terabytes or petabytes of data with army of shell scripts &#8211; as there&#8217;re no nice frameworks to explain what you want to do in MySQL administration. The nice thing about proper object frameworks [...]]]></description>
			<content:encoded><![CDATA[<p>In the age of jetsetting and space travel and ORMs and such, MySQL DBAs are the least sophisticated ones nowadays, usually fighting terabytes or petabytes of data with army of shell scripts &#8211; as there&#8217;re no nice frameworks to explain what you want to do in MySQL administration. The nice thing about proper object frameworks is that they allow to concentrate on the work and logic done, allowing to think on the process done, rather on languages/APIs/etc.</p>
<p>For example, moving a slave to another master down a replication topology could be expressed this way (this is a working code, actually):</p>
<pre>
slave = mysql(options.slave)
oldmaster = mysql(slave.get_master())
newmaster = mysql(options.newmaster)

oldmaster.lock()
oldpos = oldmaster.pos()
newmaster.wait(oldpos)
newmaster.lock()
oldmaster.unlock()
slave.wait(oldpos)
slave.change_master(newmaster)
newmaster.unlock()
</pre>
<p>I&#8217;m sure transaction group/global IDs would simplify the process a lot, but still, having building blocks one can write pretty much self-documenting narrow code, shuffle actions done without having to rethink whole programming logic too much. Implementation of methods like .sync(), .clone(), .promote() ends up environment-specific, but may save quite some time afterwards too. </p>
<p>As much as I&#8217;d like everyone around to get their data management actions written down into scripts, I&#8217;d like every DBA action I do to be written down in such code too :-) I&#8217;d love to have code, which detects resource shortages, orders servers, deploys software and re-shards data automatically&#8230; well, you know what I mean :)</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/08/17/dba-python-scripts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Evil replication management</title>
		<link>http://mituzas.lt/2009/07/30/evil-replication-management/</link>
		<comments>http://mituzas.lt/2009/07/30/evil-replication-management/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 12:46:02 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[evil]]></category>
		<category><![CDATA[gdb]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=567</guid>
		<description><![CDATA[When one wants to script automated replication chain building, certain things are quite annoying, like immutable replication configuration variables. For example, at certain moments log_slave_updates is more than needed, and thats what the server says:

mysql> show variables like 'log_slave_updates';
+-------------------+-------+
&#124; Variable_name     &#124; Value &#124;
+-------------------+-------+
&#124; log_slave_updates &#124; OFF   &#124;
+-------------------+-------+
1 row in [...]]]></description>
			<content:encoded><![CDATA[<p>When one wants to script automated replication chain building, certain things are quite annoying, like immutable replication configuration variables. For example, at certain moments log_slave_updates is more than needed, and thats what the server says:</p>
<pre>
mysql> show variables like 'log_slave_updates';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| log_slave_updates | OFF   |
+-------------------+-------+
1 row in set (0.00 sec)

mysql> set global log_slave_updates=1;
ERROR 1238 (HY000): Variable 'log_slave_updates' is a read only variable
</pre>
<p>Of course, there are few options, roll in-house fork (heheeeee!), restart your server, and keep warming up your tens of gigabytes of cache arenas, or wait for MySQL to ship a feature change in next major release. Then there are evil tactics:</p>
<pre>
mysql> system gdb -p $(pidof mysqld)
                       -ex "set opt_log_slave_updates=1" -batch
mysql> show variables like 'log_slave_updates';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| log_slave_updates | ON    |
+-------------------+-------+
1 row in set (0.00 sec)
</pre>
<p>I don&#8217;t guarantee safety of this when slave is running, but&#8230; stopping and starting slave threads is somewhat cheaper, than stopping and starting big database instance, right?</p>
<p>What else can we do? </p>
<pre>
mysql> show slave status \G
...
     Replicate_Do_DB: test
...
mysql> system gdb -p $(pidof mysqld)
          -ex 'call rpl_filter->add_do_db(strdup("hehehe"))' -batch
mysql> show slave status \G
...
      Replicate_Do_DB: test,hehehe
...
</pre>
<p>It is actually possible to add all sorts of filters this way, rpl_filter.h can be good reference :) So now that you want to throw out some data from your slaves, restart isn&#8217;t needed. Unfortunately, deleting entries isn&#8217;t possible via rpl_filter methods, but you can always edit base_ilists, can&#8217;t you?</p>
<p>P.S. having this functionality inside server would definitely be best. </p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/07/30/evil-replication-management/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>DBAs of all countries, unite!</title>
		<link>http://mituzas.lt/2009/07/29/dbas-of-all-countries-unite/</link>
		<comments>http://mituzas.lt/2009/07/29/dbas-of-all-countries-unite/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 09:21:08 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[dba]]></category>
		<category><![CDATA[procedures]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=562</guid>
		<description><![CDATA[I&#8217;m observing the process of most awesome SHOW commands being abolished, destroyed and some weird information_schema tables are introduced instead. 
Say, even though you can select configuration variables using @@syntax, you can&#8217;t do same for much more interesting to DBAs status variables in any more interesting logic. 
Apparently instead of doing
SHOW STATUS LIKE "questions"
one has [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m observing the process of most awesome SHOW commands being abolished, destroyed and some weird information_schema tables are introduced instead. </p>
<p>Say, even though you can select configuration variables using @@syntax, you can&#8217;t do same for much more interesting to DBAs status variables in any more interesting logic. </p>
<p>Apparently instead of doing</p>
<pre>SHOW STATUS LIKE "questions"</pre>
<p>one has to do this now (I&#8217;m being dramatic here, above hasn&#8217;t been removed yet, but hasn&#8217;t been expanded for better usage either):</p>
<pre>
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_STATUS
WHERE VARIABLE_NAME="QUESTIONS"</pre>
<p>Do note, those SQL standard followers will get caps-lock button swapped with space bar soon. </p>
<p>Of course, we, DBAs, know that one can simplify stuff by creating stored routines:</p>
<pre>
CREATE FUNCTION `gstatus`(v varchar(64)) returns varchar(1024)
return
( SELECT variable_value
  FROM information_schema.global_status
  where variable_name=v LIMIT 1
)
</pre>
<p>So we can do such simple things as: </p>
<pre>
mysql> select m.gstatus("questions");
+------------------------+
| m.gstatus("questions") |
+------------------------+
| 140                    |
+------------------------+
1 row in set (0.00 sec)
</pre>
<p>Of course, this leads to solution of one of most common DBA problems, how to get decent status variable values per time:</p>
<pre>
CREATE PROCEDURE m.report(in timer float)
begin

DROP TEMPORARY TABLE IF EXISTS status_old;
CREATE TEMPORARY TABLE status_old
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS;

SELECT SLEEP(timer) into @x;
SELECT
    s.variable_name status,
    (s.variable_value-o.variable_value)/timer value
FROM INFORMATION_SCHEMA.GLOBAL_STATUS s
    JOIN status_old o USING (variable_name)
WHERE s.variable_value>0;

DROP TEMPORARY TABLE status_old;

end
</pre>
<p>So, the &#8220;show me changes-per-second for values in last 0.5s&#8221; would look like this:</p>
<pre>
ysql> call m.report(0.5) //
+-----------------------------------+---------+
| status                            | value   |
+-----------------------------------+---------+
| ABORTED_CLIENTS                   |       0 |
| ABORTED_CONNECTS                  |       0 |
| BYTES_RECEIVED                    |  532662 |
| BYTES_SENT                        | 1140894 |
...
| QUERIES                           |    2884 |
| QUESTIONS                         |    2878 |
| SELECT_FULL_JOIN                  |       2 |
| SELECT_RANGE                      |     196 |
| SELECT_SCAN                       |     146 |
...
| THREADS_CACHED                    |      12 |
| THREADS_CONNECTED                 |     -28 |
| THREADS_CREATED                   |       4 |
| THREADS_RUNNING                   |      -2 |
| UPTIME                            |       2 |
| UPTIME_SINCE_FLUSH_STATUS         |       2 |
+-----------------------------------+---------+
125 rows in set (0.53 sec)

Query OK, 0 rows affected, 1 warning (0.54 sec)
</pre>
<p>So, by spending five minutes on writing very simple INFORMATION_SCHEMA procedure we can resolve one of usual nightmares in MySQL DBA environments. </p>
<p>I can get back now to the initial idea of this post &#8211; if one DBA can write such small neat thing in few minutes, would you imagine how useful can a collaboratively built repository of DBA-assisting stored procedures in functions, and how we can spit at all the SQL standard verbosity, and make our systems easy to manage? :) I think we shouldn&#8217;t allow not to share such utilities, as widespread use and &#8220;expect it already there&#8221; would make overall work much much easier. Let&#8217;s use and reuse (and someone should set up framework for building such thing ;-))</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/07/29/dbas-of-all-countries-unite/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Board again (perhaps)</title>
		<link>http://mituzas.lt/2009/07/27/board-again-perhaps/</link>
		<comments>http://mituzas.lt/2009/07/27/board-again-perhaps/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 21:03:50 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[wikipedia]]></category>
		<category><![CDATA[wikitech]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=560</guid>
		<description><![CDATA[Tomorrow voting for Wikimedia Foundation Board of Trustees Election starts &#8211; and Yours truly is a candidate. 
You can find most of my views on various issues in our question pages (I was somewhat boiling when answering the What will you do about the WMF mishandling it&#8217;s funding? one &#8211; it probably takes great effort [...]]]></description>
			<content:encoded><![CDATA[<p>Tomorrow voting for <a href='http://wikimediafoundation.org'>Wikimedia Foundation</a> <a href='http://wikimediafoundation.org/wiki/Board'>Board of Trustees</a> Election starts &#8211; and Yours truly is a <a href='http://meta.wikimedia.org/wiki/Board_elections/2009/Candidates/en#Domas_Mituzas_.28Midom.29'>candidate</a>. </p>
<p>You can find most of my views on <a href='http://meta.wikimedia.org/wiki/Board_elections/2009/Candidates/Questions/1'>various issues</a> in our question pages (I was somewhat boiling when answering the <i>What will you do about the WMF mishandling it&#8217;s funding?</i> one &#8211; it probably takes great effort to phrase such a bad question, and so easy to answer it :), as well as <a href='http://en.wikipedia.org/wiki/Wikipedia:Wikipedia_Signpost/2009_Board_elections/Domas_Mituzas'>Wikipedia Signpost</a> &#8216;interview&#8217;. </p>
<p>I was appointed to the Board back in January 2008, after holding various other volunteer (at some point in time &#8211; &#8216;officer&#8217;) positions within the organization since 2004 &#8211; and brought in the core technology and operational efficiency skill set there. The appointment was supposed to be somewhat temporary, but board restructure appeared to be much longer process than we expected &#8211; both the chapters part, and nomination committee work. As a community member, after the restructure I was in &#8216;community-elected&#8217; seat, though I never participated in any election &#8211; so that wasn&#8217;t too fair to the actual community, need to fix that :)</p>
<p>So, even though I wasn&#8217;t too visible to actual community (people would notice me mostly when things go wrong, and I&#8217;m not in best mood then, usually :-), I feel that the values I&#8217;ve worked on, evangelized and supported for all these years &#8211; efficiency and general availability of our projects &#8211; can win mindshare not only of our read-only users I work mostly for, but also eligible voters. </p>
<p>And I do think, that internal technology expertise has to be represented on board, as things we&#8217;ve been doing, and methods we&#8217;ve been using, are very much unique in the technology world. Oh, and somewhere I mentioned, our technology spending is close to 50%, that has to be represented too :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/07/27/board-again-perhaps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Profile guided optimization with gcc</title>
		<link>http://mituzas.lt/2009/07/27/profile-guided-optimization-with-gcc/</link>
		<comments>http://mituzas.lt/2009/07/27/profile-guided-optimization-with-gcc/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 13:27:38 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[gcc]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=554</guid>
		<description><![CDATA[Yesterday I wrote how certain build optimizations can have performance differences &#8211; and I decided to step a bit deeper into a quite interesting field &#8211; profile guided binary optimization. There&#8217;re quite a few interesting projects out there, like LLVM (I hear it is used extensively in iphone?) &#8211; which analyze run-time profile of compiled [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I wrote how certain build optimizations can have performance differences &#8211; and I decided to step a bit deeper into a quite interesting field &#8211; profile guided binary optimization. There&#8217;re quite a few interesting projects out there, like LLVM (I hear it is used extensively in iphone?) &#8211; which analyze run-time profile of compiled code and can do just in time adjustments of binary code. Apparently, you don&#8217;t need that fancy technology, and can use plain old gcc. </p>
<p>The whole plan is:</p>
<ol>
<li>Compile all code with -fprofile-generate in {C|CXX|LD}FLAGS</li>
<li>Run the binary</li>
<li>Run your application/benchmark against that binary</li>
<li>Recompile all code with -fprofile-use (above steps will place lots of .gcda files in source tree)</li>
<li>PROFIT!!! (note the omission of <a href='http://en.wikipedia.org/wiki/File:Gnomes_plan.png'>&#8220;???&#8221;</a> step)
</li>
</ol>
<p>How much profit? I measured <b>~7%</b> of sysbench performance increase (and probably would see much higher value in CPU-tight benchmarks). YMMV. Can such PGO be useful for every user out there? Maybe &#8211; but the best results are achieved once looking at actual use patterns &#8211; though of course, lots of them are similar everywhere around. </p>
<p>Also, I am showing the actual profiling process with too much of pink. Apparently gcc/gcov profiles tend to get corrupted in multithreaded applications, so I did multiple profile/build passes, until I managed to assemble final binary. :-)</p>
<p>Now I have to figure out how to use -combine flag in gcc, and treat whole MySQL codebase as one huge .c file (apparently compilers can make much much better decisions then). </p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/07/27/profile-guided-optimization-with-gcc/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>On binaries and -fomit-frame-pointer</title>
		<link>http://mituzas.lt/2009/07/26/on-binaries-and-fomit-frame-pointer/</link>
		<comments>http://mituzas.lt/2009/07/26/on-binaries-and-fomit-frame-pointer/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 21:16:17 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[compiling]]></category>
		<category><![CDATA[gdb]]></category>
		<category><![CDATA[oprofile]]></category>
		<category><![CDATA[x86_64]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=545</guid>
		<description><![CDATA[Over last few years 64-bit x86 platform has became ubiquitous, thus making stupid memory limitations a thing of some forgotten past. 64-bit processors made internal memory structures bigger, but compensated that with twice the amount and twice larger registers. 
But there&#8217;s one thing that definitely got worse &#8211; gcc, the compiler, has a change in [...]]]></description>
			<content:encoded><![CDATA[<p>Over last few years 64-bit x86 platform has became ubiquitous, thus making stupid memory limitations a thing of some forgotten past. 64-bit processors made internal memory structures bigger, but compensated that with twice the amount and twice larger registers. </p>
<p>But there&#8217;s one thing that definitely got worse &#8211; gcc, the compiler, has a change in default compilation options &#8211; it omits frame pointers from binaries in x86_64 architecture. People have advocated against that <a href='http://lkml.indiana.edu/hypermail/linux/kernel/9702.3/0214.html'>back in 1997</a> because of very simple reasons, that are still very much existing today too &#8211; frame pointers are needed for efficient stack trace calculations, and stack traces are very very useful, sometimes. </p>
<p>So, this change means that oprofile is not able to give hierarchical profiles, it also means that MySQL crash information will not include most useful bit &#8211; the failing stack trace. This decision has been just because of performance reasons &#8211; frame pointer takes whole register (though on x86_32 that meant 1 out of 8, on x86_64 it is 1 out of 16), which could be used to optimize the application. </p>
<p>I tested two MySQL builds, one built with &#8216;-O3 -g -fno-omit-frame-pointer&#8217; and other with -fomit-frame-pointer instead &#8211; and performance difference was negligible. It was around <b>1%</b> in sysbench tests, and slightly over <b>3%</b> at tight-loop <code>select benchmark(100000000,(select asin(5+5)+sin(5+5)));</code> on a 2-cpu Opteron box.</p>
<p>The summary suggestion for this flag would be very simple. If you don&#8217;t care about fixing or making your product faster, you can probably use 1% speed-up. But if getting actual real-time performance data can lead to much better performance fixes, and fast introspection means qualified engineers can diagnose problems much faster, 1% or even 3% is not that much. So, add &#8216;-fno-omit-frame-pointer&#8217; to CFLAGS and CXXFLAGS, and enjoy things getting back to normal :) </p>
<p>By the way, while I was at it, I did some empiric tests of other options, but one that irks me most is not using &#8216;-g&#8217; on production binaries. See, debugging information, symbol tables, etc &#8211; they all cause around 0% performance difference. The only difference is that e.g. mysqld binary will weight 30M, instead of 6M (though that fat will not be loaded into RAM, and will only cost diskspace). </p>
<p>Why does debugging information matter? It doesn&#8217;t, if you don&#8217;t attempt to be power-user. It does, if you enjoy crazy debugger tricks (like one <a href='http://mituzas.lt/2009/05/28/checksums-again-some-io-too/'>here</a> or <a href='http://mituzas.lt/2009/03/14/stupid-innodb-tricks/'>here</a>). Oh, and of course, bonus GDB trick, how to run KILL without connecting to server:</p>
<pre>
(gdb) thread apply all bt
...
(gdb) thread 2
[Switching to thread 2 (Thread 0x44a76950 (LWP 23955))]#0  ...
(gdb) bt
#0  0x00007f7821e68e1d in pthread_cond_timedwait...
#1  0x000000000052dc0e in Item_func_sleep::val_int (this=0x12317f0)...
#2  0x0000000000501484 in Item::send (this=0x12317f0, ...
...
#15 0x00000000005caf29 in do_command (thd=0x11da290) ...
...
(gdb) frame 15
#15 0x00000000005caf29 in do_command (thd=0x11da290) at sql_parse.cc:854
854	  return_value= dispatch_command(command, thd, packet+1, ...
(gdb) set thd->killed = THD::KILL_QUERY
(gdb) continue
</pre>
<p>And the client gets <i>&#8216;ERROR 1317 (70100): Query execution was interrupted&#8217;</i> :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/07/26/on-binaries-and-fomit-frame-pointer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Brute force!</title>
		<link>http://mituzas.lt/2009/07/09/brute-force/</link>
		<comments>http://mituzas.lt/2009/07/09/brute-force/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 11:30:02 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=538</guid>
		<description><![CDATA[More than three years ago one prominent Wikipedia community member, who didn&#8217;t have enough time to work on our technology, but had enough of it to criticize it, had a problem. He was working for a super-computing lab that boasted one of fastest world&#8217;s clusters (IBM blue-something), and to relieve the stress of some of [...]]]></description>
			<content:encoded><![CDATA[<p>More than three years ago one prominent Wikipedia community member, who didn&#8217;t have enough time to work on our technology, but had enough of it to criticize it, had a problem. He was working for a super-computing lab that boasted one of fastest world&#8217;s clusters (IBM blue-something), and to relieve the stress of some of his hard work, was trying to solve a computer science mystery:</p>
<blockquote><p>Given a dictionary, find words that have most anagrams. With few-hundred-thousand word dictionary, on 8-way machine this should complete in less than 12 hours.</p></blockquote>
<p>The supercomputing lab inspired solution was something like this (I may be wrong, years pass though):</p>
<ul>
<li>Put all the words into an array</li>
<li>Start generating letter sequences: aaaa, aaab, aaac, &#8230;</li>
<li>For every generated word, traverse the array, find how many matches it hits</li>
<li>Get sequences with most matches</li>
</ul>
<p>See, the problem was not how to make this algorithm efficient, but how to parallelize it, or maybe rewrite in C (thats what they do in supercomputing labs). It took few minutes to write following code:</p>
<pre>
wordlist=open("/usr/share/dict/words")
anagrams={}
for line in wordlist:
  word=line.strip()
  sorted=list(word)
  sorted.sort()
  sorted="".join(sorted)
  if sorted not in anagrams:
    anagrams[sorted]={'count':1,'words':[word,]}
  else:
    anagrams[sorted]['count']+=1
    anagrams[sorted]['words'].append(word)
</pre>
<p>(I just canonized words into base-anagram-form &#8211; sorted letters, and ran collision test)</p>
<p>It took maybe half a second to run it on my 1.2ghz ibook back then. The end of the story back then was that we get one critic less.</p>
<p>Now, why I remember this story today &#8211; <a href='http://www.mysqlperformanceblog.com/2009/07/07/improving-innodb-recovery-time/'>Yasufumi Kinoshita just did exactly the same</a> to us, MySQL users. Simply, brute force is not the answer, if you can spare the minute and rethink stuff. Thanks, for reminding this. </p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/07/09/brute-force/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>query cache tuning</title>
		<link>http://mituzas.lt/2009/07/08/query-cache-tuning/</link>
		<comments>http://mituzas.lt/2009/07/08/query-cache-tuning/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 18:22:35 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=536</guid>
		<description><![CDATA[For anyone, who has questions about MySQL query cache tuning, try this tuning assistant:
http://mituzas.lt/tech/query-cache-tuner/
]]></description>
			<content:encoded><![CDATA[<p>For anyone, who has questions about MySQL query cache tuning, try this tuning assistant:</p>
<p><a href='http://mituzas.lt/tech/query-cache-tuner/'>http://mituzas.lt/tech/query-cache-tuner/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/07/08/query-cache-tuning/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Knight&#8217;s Cross!</title>
		<link>http://mituzas.lt/2009/07/05/knights-cross/</link>
		<comments>http://mituzas.lt/2009/07/05/knights-cross/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 14:27:10 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[wikipedia]]></category>
		<category><![CDATA[dad]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=522</guid>
		<description><![CDATA[
We had very special State Award Ceremony today. Special, as it happens at the year we celebrate &#8220;thousand years of Lithuania&#8221;, special as it is the last one given by our very special President Valdas Adamkus. 
Though for me, it was really special &#8211; Alvydas Mituzas, my Dad, got a Knight&#8217;s Cross, for his lifetime [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/midom/3689536125/" title="Celebrating the Knight's Cross by midom, on Flickr"><img src="http://farm4.static.flickr.com/3644/3689536125_4dd24b1907_m.jpg" width="240" height="180" alt="Celebrating the Knight's Cross" style="float: right; padding: 10px;" /></a><br />
We had very special <a href='http://www.lrp.lt/en/activities/speeches/address_by_h.e._valdas_adamkus_president_of_the_republic_of_lithuania_at_the_state_awards_ceremony_on_the_occasion_of_the_day_of_coronation_of_king_mindaugas.html'>State Award Ceremony</a> today. Special, as it happens at the year we celebrate &#8220;thousand years of Lithuania&#8221;, special as it is the last one given by our very special President <a href='http://en.wikipedia.org/wiki/Valdas_Adamkus'>Valdas Adamkus</a>. </p>
<p>Though for me, it was really special &#8211; Alvydas Mituzas, my Dad, got a Knight&#8217;s Cross, for his lifetime merits and service for our country, spanning forty years of creativity and dedication. Anyone knowing my Dad really know what the award is for, but for me it is also a symbol of support for virtues that I&#8217;ve seen in my whole life &#8211; hard work and imagination combined for public service and public good, no matter how difficult it is to start, or finish. Stories of his past are fascinating, and even I can learn more and more of them over the years. We&#8217;re proud of him, and we&#8217;re lucky to be his family. </p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/07/05/knights-cross/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>On file system benchmarks</title>
		<link>http://mituzas.lt/2009/06/30/on-file-system-benchmarks/</link>
		<comments>http://mituzas.lt/2009/06/30/on-file-system-benchmarks/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 19:34:35 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[xfs]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=519</guid>
		<description><![CDATA[I see this benchmark being quoted in multiple places, and there I see stuff like:
When carrying out more database benchmarking, but this time with PostgreSQL, XFS and Btrfs were too slow to even complete this test, even when it had been running for more than an hour for a single run. Between EXT3, EXT4, and [...]]]></description>
			<content:encoded><![CDATA[<p>I see <a href="http://www.phoronix.com/scan.php?page=article&amp;item=ext4_btrfs_nilfs2">this benchmark</a> being quoted in multiple places, and there I see stuff like:</p>
<blockquote><p>When carrying out more database benchmarking, but this time with PostgreSQL, XFS and Btrfs were too slow to even complete this test, even when it had been running for more than an hour for a single run. Between EXT3, EXT4, and NILFS2, the fastest file-system was EXT3 and then its successor, EXT4, was slightly behind that. Far behind the position of EXT4 were NILFS2 and then Btrfs and XFS.</p></blockquote>
<p>There were few other benchmarks, e.g. SQLite showed &#8216;bad performance&#8217; on XFS and Btrfs.</p>
<p>*clear throat*</p>
<p>Dear benchmarkers, don&#8217;t compare apples and oranges. If you see differences between benchmarks, do some very very tiny research, and use some intellect, that you, as primates, do have. If database tests are slowest on filesystems created by Oracle (who know some stuff about systems in general) or SGI (who, despite giving away their campus to Google, still have lots of expertise in the field), that can indicate, that your tests are probably flawed somewhere, at least for that test domain.</p>
<p>Now, probably you&#8217;ve heard about such thing as &#8216;data consistency&#8217;. That is something what database stack tries to ensure, sometimes at higher costs, like not trusting volatile caches, enforcing certain write orders, depending on acknowledgements by underlying hardware.</p>
<p>So, in this case it wasn&#8217;t &#8220;benchmarking file systems&#8221;, it was simply, benchmarking &#8220;consistency&#8221; against &#8220;no consistency&#8221;. But don&#8217;t worry, most benchmarks have such flaws &#8211; getting numbers but not understanding them makes results much more interesting, right?</p>
<p>Oh, and&#8230; thanks for few more misguided people.</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/06/30/on-file-system-benchmarks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>uncache!</title>
		<link>http://mituzas.lt/2009/06/26/uncache/</link>
		<comments>http://mituzas.lt/2009/06/26/uncache/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 11:40:50 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://dammit.lt/?p=512</guid>
		<description><![CDATA[this is source code for a tiny program I just wrote that traverses specified directories and removes them from file system cache. 
There are few use cases for it. One is for all these people who benchmark stuff and want selective OS cache purges, another is for those who run high performance databases. Remember the [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://bazaar.launchpad.net/%7Edomas-mituzas/%2Bjunk/uncache/annotate/head%3A/uncache.c'>this is source code for a tiny program</a> I just wrote that traverses specified directories and removes them from file system cache. </p>
<p>There are few use cases for it. One is for all these people who benchmark stuff and want selective OS cache purges, another is for those who run high performance databases. Remember the <a href='http://mituzas.lt/2008/08/11/notes-from-land-of-io/'>O_DIRECT serialization</a> everywhere? Well, XFS does direct I/O in parallel, unless there are cached pages (and they can happen because of any random outside-of-database activity, like &#8216;file&#8217; command). Once you &#8216;uncache&#8217; the files, XFS will be very much parallel again \o/ \o/</p>
]]></content:encoded>
			<wfw:commentRss>http://mituzas.lt/2009/06/26/uncache/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
