<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>domas mituzas &#187; performance</title>
	<atom:link href="http://dom.as/tag/performance/feed/" rel="self" type="application/rss+xml" />
	<link>http://dom.as</link>
	<description></description>
	<lastBuildDate>Thu, 02 Feb 2012 21:29:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='dom.as' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/6e344c6e0cd7462eb056f8b98eb2cbcd?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>domas mituzas &#187; performance</title>
		<link>http://dom.as</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://dom.as/osd.xml" title="domas mituzas" />
	<atom:link rel='hub' href='http://dom.as/?pushpress=hub'/>
		<item>
		<title>On connections</title>
		<link>http://dom.as/2011/08/28/mysql-connection-accept-speed/</link>
		<comments>http://dom.as/2011/08/28/mysql-connection-accept-speed/#comments</comments>
		<pubDate>Sun, 28 Aug 2011 23:51:04 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[facebook]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[connections]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://dom.as/?p=897</guid>
		<description><![CDATA[MySQL is needlessly slow at accepting new connections. People usually work around that by having various sorts of connection pools, but there’s always a scale at which connection pools are not feasible. Sometimes connection avalanches come unexpected, and even if &#8230; <a href="http://dom.as/2011/08/28/mysql-connection-accept-speed/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=897&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>MySQL is needlessly slow at accepting new connections. People usually work around that by having various sorts of connection pools, but there’s always a scale at which connection pools are not feasible. Sometimes connection avalanches come unexpected, and even if MySQL would have no trouble dealing with queries, it will have problems letting clients in. Something has to be done about it.</p>
<p>Lots of these problems have been low hanging fruits for years &#8211; it ‘was not detected’ by benchmarks because everyone who benchmarks MySQL would know that persistent connections are much faster and therefore wouldn’t look at connection speeds anymore.</p>
<p>Usually people attribute most of slowness to the LOCK_thread_count mutex &#8211; they are only partially right. This mutex does not just handle the counter of active running connections, but pretty much every operation that deals with increase or decrease of threads (thread cache, active thread lists, etc) has to hold it for a while.</p>
<p>Also, it is common wisdom to use <a href="http://dev.mysql.com/doc/refman/5.5/en/connection-threads.html">thread cache</a>, but what people quite often miss is that thread cache is something that was created back when OS threads were extremely expensive to create, and all it does is caching pthreads. It does not do any of MySQL specific thread caching magic &#8211; everything gets completely reinitialized for each incoming structure.</p>
<p>I decided to attack this problem based on very simple hypothesis &#8211; whatever ‘accept thread’ is doing, is bottleneck for whole process. It is very simple to analyze everything from this perspective (and I had some success looking at replication threads from this perspective).</p>
<p>All we need is gdb and two loops &#8211; gdb attaches to accept thread, one loop does ‘breakpoint; continue’, another sends signals at a certain sampling rate (I picked 10Hz in order to avoid profiling bias). I <a href="https://www.facebook.com/poormansprofiler/posts/147734715313155">posted</a> those scripts on <a href="https://www.facebook.com/poormansprofiler">PMP page</a>. After a lunch break I had 50k stacks (long lunch ;-) that I fed into graphviz for full data visualisation and could look at individually:</p>
<p><a href="http://domasmituzas.files.wordpress.com/2011/09/connects-5-5.png"><img class="alignnone size-full wp-image-1170" title="5.5 accept thread time analysis" src="http://domasmituzas.files.wordpress.com/2011/09/connects-5-5.png?w=640" alt=""   /></a></p>
<p>A picture is worth thousand words (well, is easier than looking at thousands of lines in stack aggregations), and I immediately noticed few things worth looking at:</p>
<ul>
<li>Initializing THD (MySQL thread) structure is CPU-heavy task that resides in choke-point thread</li>
<li>There is way too much time spent in syscalls, whatever they do</li>
<li>Too much memory allocation done by the master thread</li>
<li>There’s mutex contention on thread cache waking up worker threads</li>
<li>There’s needless mutex contention in few other places</li>
</ul>
<p>I didn’t want to look at mutex contention issues first so I ended up with something as simple as looking at syscall costs.</p>
<ul>
<li>15% was going into actual accept()</li>
<li>8.5% was going into poll()</li>
<li>8% went into fcntl()</li>
<li>7% went into setsockopt()</li>
<li>1.2% went into getsockname()</li>
</ul>
<p>An strace on mysqld gives a picture that explains quite a bit:<br />
<code><br />
poll([{fd=12, ...}, {fd=13, ...}], 2, -1) = 1<br />
fcntl(12, F_GETFL) = 0x2 (flags O_RDWR)<br />
fcntl(12, F_SETFL, O_RDWR|O_NONBLOCK) = 0<br />
accept(12, {... sin_port=htons(59183), ...) = 32<br />
fcntl(12, F_SETFL, O_RDWR)<br />
getsockname(32, {... sin_port=htons(3306), ...) = 0<br />
fcntl(32, F_SETFL, O_RDONLY) fcntl(32, F_GETFL) = 0x2 (flags O_RDWR)<br />
setsockopt(32, SOL_SOCKET, SO_RCVTIMEO, ...)<br />
setsockopt(32, SOL_SOCKET, SO_SNDTIMEO, ...)<br />
fcntl(32, F_SETFL, O_RDWR|O_NONBLOCK)<br />
setsockopt(32, SOL_IP, IP_TOS, [8], 4)<br />
setsockopt(32, SOL_TCP, TCP_NODELAY, [1], 4)<br />
</code></p>
<p>I’ll skip walking through the code, but essentially what it does here is (12 is accept socket, 32 is connection socket):</p>
<ul>
<li>poll() checks whether there are pending connections. If server is busy, trying to accept first, poll on failure is a better approach. There are side effects with that idea though &#8211; other sockets may starve a bit, but it is solvable by injecting occasional poll.</li>
<li>What happens next is a bit sad. Instead of storing per-socket flags (nobody is touching that for now anyway), it gets the socket flags, figures out it is a blocking socket, sets it to nonblocking mode, accepts the connection, sets it back to blocking mode. Just setting to nonblocking at the start and using it forever that way is much cheaper and constipates way less.</li>
<li>accept() itself can be scaled only by having parallel accept() threads. Maybe most of this post would be not necessary if there were multiple accept threads, but I’m not eager to go into that kind of refactoring for now.</li>
<li>getsockname() is used just to verify if socket is correct (probably catching EINVAL later seems to be too complicated), it is a very pessimistic code path for a case that nearly never happens (it probably was added for some random Unix back from nineties)</li>
<li>Next fcntl “get flags” call is quite unnecessary &#8211; this is a fresh socket and one shouldn’t expect anything special within it. Later non-blocking mode is set, so that overrides whatever was obtained here.</li>
<li>Three out of four setsockopt()s are necessary evil (one turns of <a>Nagle’s algorithm</a>, two other set socket timeouts), so they have to be done before network I/O is done on the socket. Fourth setsockopt() is usually completely useless &#8211; not every network observes <a href="http://en.wikipedia.org/wiki/Type_of_Service">IP_TOS header</a>, and one has to talk to network administrator first about decent values. I’d say it can be optional parameter (yay, more tuning options).</li>
</ul>
<p>Pretty much every connection socket operation can be done later, in a worker thread, without consuming expensive accept thread time, and pretty much every syscall except accept() can be removed from a busy accept thread(), which is what I did in my testing build.</p>
<p>Once I got rid of syscalls I started looking at other low hanging fruits. The most obvious one was sprintf() called inside vio_new(). Though it accounted only for 4% of thread time, the uselessness of it was depressing. Here it is:</p>
<pre>sprintf(vio-&gt;desc,
   (vio-&gt;type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
   vio-&gt;sd);</pre>
<p>It formats a string that is not used at all by production builds (only few DBUG messages are calling vio_description()). Though I removed this code in non-debug build, as I was moving over network initialization to worker threads, whole my_net_init() and vio() ended up outside of accept thread anyway ;-)</p>
<p>The overall thread cache design is centered around LOCK_thread_count &#8211; lock is held while signaling threads, and threads that wake up need the lock too &#8211; so there’s lots of overhead involved in the coordination &#8211; 13% of time is spent just to pass the task to a worker thread.</p>
<p>Allowing multiple threads to wake up and multiple entries to be placed into thread cache before it is all drained (more of an InnoDB concurrency-queue with FLIFO approach) could be somewhat better &#8211; so would be worker threads accepting connections directly (I already said that, I guess). There’s simply too much time wasted waking up and sending threads to sleep, and quite some of that time is on a choke point.</p>
<p>THD initializations are somewhat simpler, as they don’t include SMP madness.</p>
<p>There’re some low hanging fruits of course there as well. For example THD initializer calls sql_rnd_with_mutex(), which locks thread count mutex. Simplest fix could be using another mutex, though lockless random function or on-demand variable initialization would help too.</p>
<p>Some initializers there are quite expensive too &#8211; e.g. Warning_info class could initialize dynamic storage only when actually used, and not at THD initialization chokepoint. THD::init can be moved to a worker thread, and lots of THD initialization could be moved over to it.</p>
<p>Quite a lot of time (12%) is spent on malloc() &#8211; and lots of that is for allocating lots of various fixed-size structures &#8211; slab allocator (or just more efficient malloc implementation) could cut on CPU time there. Of course, more drastic alternative is not dealing with THD at all during accept phase &#8211; one can pass stub structure to build upon later, or (oh, am I writing this again) moving accept() part to individual workers.</p>
<p>So far I tested just few optimizations &#8211; moved over vio/net initialization to worker threads, reduced number of syscalls, added a new mutex for rand initialization, and that alone got me <strong>additional 50% increase</strong> in connection accepts. Think how much more one could get from fixing this problem properly ;-)</p>
<p><strong>TL;DR:</strong> MySQL sucks at accepting new connections, but there’re lots of low hanging fruit there. Ask your MySQL provider for a fix.</p>
<p>MySQL bug entries:</p>
<ul>
<li>rand(): <a href="http://bugs.mysql.com/bug.php?id=62282">#62282</a></li>
<li>fcntl on accept(): <a href="http://bugs.mysql.com/bug.php?id=62283">#62283</a></li>
<li>network init costs: <a href="http://bugs.mysql.com/bug.php?id=62284">#62284</a></li>
<li>vio sprintf(): <a href="http://bugs.mysql.com/bug.php?id=62285">#62285</a></li>
<li>poll() vs accept(): <a href="http://bugs.mysql.com/bug.php?id=62286">#62286</a></li>
<li>thread cache performance: <a href="http://bugs.mysql.com/bug.php?id=62287">#62287</a></li>
<li>THD initialization: <a href="http://bugs.mysql.com/bug.php?id=62288">#62288</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/897/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/897/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/897/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/897/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/897/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/897/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/897/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/897/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/897/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/897/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/897/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/897/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/897/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/897/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=897&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2011/08/28/mysql-connection-accept-speed/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>

		<media:content url="http://domasmituzas.files.wordpress.com/2011/09/connects-5-5.png" medium="image">
			<media:title type="html">5.5 accept thread time analysis</media:title>
		</media:content>
	</item>
		<item>
		<title>InnoDB locking makes me sad</title>
		<link>http://dom.as/2011/07/03/innodb-index-lock/</link>
		<comments>http://dom.as/2011/07/03/innodb-index-lock/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 11:05:00 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[facebook]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[innodb]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[mutex]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://dom.as/?p=873</guid>
		<description><![CDATA[Vadim and others have pointed at the index-&#62;lock problems before, but I think they didn&#8217;t good job enough at pointing out how bad it can get (the actual problematic was hidden somewhere as some odd edge case). What &#8216;index lock&#8217; &#8230; <a href="http://dom.as/2011/07/03/innodb-index-lock/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=873&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Vadim and others have <a href='http://www.mysqlperformanceblog.com/2010/02/25/index-lock-and-adaptive-search-next-two-biggest-innodb-problems/'>pointed</a> at the index-&gt;lock problems before, but I think they didn&#8217;t good job enough at pointing out how bad it can get (the actual problematic was hidden somewhere as some odd edge case). What &#8216;index lock&#8217; means is generally the fact that InnoDB has table-level locking which will kill performance on big tables miserably.</p>
<p>InnoDB is a huge pie of layers, that have various locking behaviors, and are layered on top of each other, and are structured nicely as subdirectories in your innodb_plugin directory. Low level storage interfaces are done via os/ routines, then on top of that there&#8217;s some file space manager, fsp/, which allocates space for btr/ to live in, where individual page/ entities live, with multiple row/ pieces. There&#8217;re few other subsystems around, that got quite some attention lately &#8211; e.g. buf/ pool, transaction log/, and large trx/ transactions are composed of micro transactions living in mtr/.</p>
<p>If you live in memory, you care about buffer pool and transaction log performance, if you write insane amounts of data to in-memory buffers you hit mtr/ problems and depend o how fast you can write out log/ or flush out buf/. If you are in I/O-heavy land most of stuff you care about happens in btr/.</p>
<p>Generally InnoDB is quite good about read scalability in I/O bound environments &#8211; nowadays one can saturate really fast I/O devices and there will be plenty of parallel reads done. Major scalability problem in this field was read-ahead which was funneling all read-ahead activity into a small set of threads, but other than that there can be hundreds of parallel reads issued to underlying devices. Situation changes when writes are added to the mix, though again, there&#8217;re few different scenarios.</p>
<p>There&#8217;re two ways for InnoDB to write out updates to pages, &#8220;optimistic&#8221; and &#8220;pessimistic&#8221;. Optimism here means that only in-page (page/row) operation will be needed without changing the tree structure. In one case you can expect quite high parallelism &#8211; multiple pages can be read for that operation at a time, multiple of them can be edited at a time, then some serialization will happen while writing out changes to redo log and undo segments. Expect good performance.</p>
<p>The much worse case is when B-Tree is supposed to be reorganized and multiple page operations can happen; thats pessimism. In this case whole index gets locked (via a read-write lock obtained from dict/),<br />
then B-Tree path is latched, then changes are done, then it is all unlocked until next row operation needs to hit the tree. Unfortunately, both &#8216;path is latched&#8217; and &#8216;changes are done&#8217; are expensive operations, and not only in-core, but are doing sync page read-ins, one at a time, which on busy systems serving lots of read load are supposed to be slow. Ironically, as no other operations can happen on the table at that time, you may find out you have spare I/O capacity.. ;-)</p>
<p>What gets quite interesting though is the actual operation needed to latch b-tree path. Usual wisdom would say that if you want to change a row (read-modify-write), you probably looked up the page already, so there won&#8217;t be I/O. Unfortunately, InnoDB uses an slightly more complicated binary tree version, where pages have links to neighbors, and tree latching does this (a bit simplified for reading clarity):</p>
<p><code><br />
/* x-latch also brothers from left to right */<br />
get_block = btr_block_get(space, zip_size, left_page_no, RW_X_LATCH, mtr);<br />
get_block = btr_block_get(space, zip_size, page_no, RW_X_LATCH, mtr);<br />
get_block = btr_block_get(space, zip_size, right_page_no, RW_X_LATCH, mtr);<br />
</code></p>
<p>So, essentially in this case, just because InnoDB is being pessimistic, it reads neighboring blocks to lock them, even if they may not be touched/accessed in any way &#8211; and bloats buffer pool at that time with tripple reads. It doesn&#8217;t cost much if whole tree fits in memory, but it is doing three I/Os in here, if we&#8217;re pessimistic about InnoDB being pessimistic (and I am). So, this isn&#8217;t just locking problem &#8211; it is also resource consumption problem at this stage.</p>
<p>Now, as the dictionary lock is hold in write mode, not only updates to this table stop, but reads too &#8211; think MyISAM kind of stop. Of course, this &#8216;table locking&#8217; happens at entirely different layer than MyISAM. In MyISAM it is statement-length locking whereas in InnoDB this lock is held just for row operation on single index, but if statement is doing multiple row operations it can be acquired multiple times.</p>
<p>Probably there exist decent workarounds if anyone wants to tackle this &#8211; grabbing read locks on the tree while reading pages into buffer pool, then escalating lock to exclusive. A bit bigger architectural change would be allowing to grab locks on neighbors (if they are needed) without bringing in page data into memory &#8211; but that needs InnoDB overlords to look at it. Talk to your closest MySQL vendor and ask for a fix!</p>
<p>How do regular workloads hit this? Larger your records are, more likely you are to have tree changes, lower your performance will be. In my edge case I was inserting 7k sized rows &#8211; even though my machine had multiple disks, once the dataset fell out of buffer pool, it couldn&#8217;t insert more than 50 rows a second, even though there were many disks idle and capacity gods cried. It gets worse with out-of-page blobs &#8211; then every operation is pessimistic.</p>
<p>Of course, there&#8217;re ways to work around this &#8211; usually by taking the hit of sharding/partitioning (this is where common wisdom of &#8220;large tables need to be partitioned&#8221; mostly comes from). Then, like with MyISAM, one will have multiple table locks and there may be some scalability then.</p>
<p>TL;DR: InnoDB index lock is major architectural performance flaw, and that is why you hear that large tables are slower. There&#8217;s a big chance that there&#8217;re more scalable engines for on-disk writes out there, and all the large InnoDB write/insert benchmarks were severely hit by this.</p>
<p><b>Update:</b> Filed bugs <a href='http://bugs.mysql.com/bug.php?id=61735'>#61735</a> and <a href='http://bugs.mysql.com/bug.php?id=61736'>#61736</a> with MySQL</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/873/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=873&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2011/07/03/innodb-index-lock/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
		<item>
		<title>MySQL metrics for read workloads</title>
		<link>http://dom.as/2011/05/19/mysql-metrics-for-read-workloads/</link>
		<comments>http://dom.as/2011/05/19/mysql-metrics-for-read-workloads/#comments</comments>
		<pubDate>Thu, 19 May 2011 13:45:43 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[facebook]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[innodb]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[profiling]]></category>

		<guid isPermaLink="false">http://dom.as/?p=861</guid>
		<description><![CDATA[There are multiple metrics that are really useful for read workload analysis, that should all be tracked and looked at in performance-critical environments. The most commonly used is of course Questions (or &#8216;Queries&#8217;, &#8216;COM_Select&#8217;) &#8211; this is probably primary finger-pointing &#8230; <a href="http://dom.as/2011/05/19/mysql-metrics-for-read-workloads/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=861&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There are multiple metrics that are really useful for read workload analysis, that should all be tracked and looked at in performance-critical environments.</p>
<p>The most commonly used is of course <strong>Questions</strong> (or &#8216;Queries&#8217;, &#8216;COM_Select&#8217;) &#8211; this is probably primary finger-pointing metric that can be used in communication with different departments (&#8220;why did your qps go up by 30%?&#8221;) &#8211; it doesn&#8217;t always reveal actual cost, it can be increase of actual request rates, it can be new feature, it can be fat fingers error somewhere in the code or improperly handled cache failure.</p>
<p>Another important to note is <strong>Connections</strong> &#8211; MySQL&#8217;s costly bottleneck. Though most of users won&#8217;t be approaching ~10k/s area &#8211; at that point connection pooling starts actually making sense &#8211; it is worth to check for other reasons, such as &#8220;maybe we connect when we shouldn&#8217;t&#8221;, or needlessly reconnect, or actually should start looking more at thread cache performance or pooling options. There&#8217;re some neighboring metrics like &#8216;Bytes_sent&#8217; &#8211; make sure you don&#8217;t hit 120MB/s on a gigabit network :-)</p>
<p>Other metrics usually are way more about what actually gets done. Major query efficiency signal for me for a long time used to be <b>Innodb_rows_read</b>. It is immediately pointing out when there are queries which don&#8217;t use indexes properly or are reading too much data. Gets a bit confusing if logical backup is running, but backup windows aside, this metric is probably one that is easy enough to track and understand. It has been extremely helpful to detect query plans gone wrong too &#8211; quite a few interesting edge cases could be resolved with FORCE INDEX (thats a topic for another post already :-)</p>
<p>For I/O heavy environments there&#8217;re few metrics that show mostly the same &#8211; <strong>Innodb_buffer_pool_reads</strong>, <strong>Innodb_data_reads</strong>, <strong>Innodb_pages_read</strong> &#8211; they all show how much your requests hit underlying storage &#8211; and higher increases ask for better data locality, more in-memory efficiency (smaller object sizes!) or simply more RAM/IO capacity.</p>
<p>For a long time lots of my metrics-oriented performance optimization could be summed up in this very simple ruleset:</p>
<ul>
<li>Number of rows shown to user in the UI has to be as close as possible to rows read from the index/table</li>
<li>Number of physical I/Os done to serve rows has to be as close to 0 as possible :-)</li>
</ul>
<p>Something I like to look at is the I/O queue size (both via iostat and from InnoDB&#8217;s point of view) &#8211; <strong>Innodb_data_pending_reads</strong> can tell how loaded your underlying storage is &#8211; on rotating media you can allow multiples of your disk count, on flash it can already mean something is odd. Do note, innodb_thread_concurrency can be a limiting factor here.</p>
<p>Overloads can be also detected from <strong>Threads_running</strong> &#8211; which is easy enough to track and extremely important quality of service data.</p>
<p>An interesting metric, that lately became more and more important for me is <strong>Innodb_buffer_pool_read_requests</strong>. Though it is often to use buffer pool efficiency in the ratio with &#8216;buffer pool reads&#8217;, it is actually much more interesting if compared against &#8216;Innodb_rows_read&#8217;. While Innodb_rows_read and Handler* metrics essentially show what has been delivered by InnoDB to upper SQL layer, there are certain expensive operations that are not accounted for, like <a href='http://dom.as/2011/01/27/a-case-for-force-index/'>index estimations</a>.</p>
<p>Though tracking this activity helps I/O quite a bit (right FORCE INDEX reduces the amount of data that has to be cached in memory), there can be also various edge cases that will heavily hit CPU itself. A rough example could be:</p>
<p>SELECT * FROM table WHERE parent_id=X and type IN (1,2,4,6,8,&#8230;,20) LIMIT 10;</p>
<p>If there was an index on (parent_id,type) this query would <i>look</i> efficient, but would actually do range estimations for each type in the query, even if they would not be fetched anymore. It gets worse if there&#8217;s separate (type) index &#8211; each time query would be executed, records-in-rage estimation would be done for each type in IN() list &#8211; and usually discarded, as going after id/type lookup is much more efficient.</p>
<p>By looking at Innodb_buffer_pool_read_requests we could identify optimizer inefficiency cases like this &#8211; and FORCE INDEX made certain queries 30x faster, even if we forced exactly same indexes. Unfortunately, there is no per-session or per-query metric that would do same &#8211; it could be extremely useful in sample based profiling analysis.</p>
<p>Innodb_buffer_pool_read_requests:Innodb_rows_read ratio can vary due to multiple reasons &#8211; adaptive hash efficiency, deeper B-Trees because of wide keys (each tree node access will count in), etc &#8211; so there&#8217;s no constant baseline everyone should adjust to.</p>
<p>I deliberately left out query cache (<a href='http://dom.as/tech/query-cache-tuner/'>here&#8217;s the reason</a>), or adaptive hash (I don&#8217;t fully understand performance implications there :). In <a href='https://code.launchpad.net/~mysqlatfacebook/mysqlatfacebook/5.1'>mysql@facebook</a> builds we have some additional extremely useful instrumentation &#8211; wall clock seconds per various server operation types &#8211; execution, I/O, parsing, optimization, etc.</p>
<p>Of course, some people may point out that I&#8217;m writing here from a stone age, and that nowadays performance schema should be used. Maybe there will be more accurate ways to dissect workload costs, but nowadays one can spend few minutes looking at metrics mentioned above and have a decent understanding what the system is or should be doing.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/861/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/861/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/861/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/861/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/861/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/861/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/861/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/861/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/861/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/861/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/861/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/861/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/861/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/861/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=861&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2011/05/19/mysql-metrics-for-read-workloads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
		<item>
		<title>A case for FORCE INDEX</title>
		<link>http://dom.as/2011/01/27/a-case-for-force-index/</link>
		<comments>http://dom.as/2011/01/27/a-case-for-force-index/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 06:57:58 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[facebook]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[force]]></category>
		<category><![CDATA[optimizer]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://dom.as/?p=834</guid>
		<description><![CDATA[I remember various discussions in different mediums where people were building cases against use of FORCE INDEX in SQL queries. I&#8217;ll hereby suggest it using way more often, but at first I&#8217;ll start with small explanation. For ages, the concept &#8230; <a href="http://dom.as/2011/01/27/a-case-for-force-index/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=834&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I remember various discussions in different mediums where people were building cases against use of FORCE INDEX in SQL queries. I&#8217;ll hereby suggest it using way more often, but at first I&#8217;ll start with small explanation.</p>
<p>For ages, the concept of index statistics affecting query plans has been clogging minds of DBAs, supported by long explanations of <a href='http://dev.mysql.com/doc/refman/5.1/en/myisam-index-statistics.html'>MyISAM</a> and <a href='http://dev.mysql.com/doc/innodb-plugin/1.0/en/innodb-other-changes-statistics-estimation.html'>InnoDB</a> manuals. Actually, statistics are used just for determining which index to use for a joined table, as predicate is not known at the time of &#8216;optimization&#8217;.</p>
<p>What happens if you do a simple query like:</p>
<blockquote><p>SELECT * FROM table WHERE a=5 AND b=6
</p></blockquote>
<p>? If there&#8217;s an index that enforces uniqueness on (a,b), it will be used &#8211; this is short-path for PRIMARY KEY lookups. Otherwise, it will go to any index, composite or not, that can satisfy either a or b (or both), and evaluate how many rows it will fetch from it using the provided criteria.</p>
<p>Now, contrary to what people usually think, the row count evaluation has nothing really much to do with cardinality statistics &#8211; instead it builds the range that the known predicate can check on existing index, and does two full B-Tree dives to the index &#8211; one at the start of the range, and one at the end of it. For each possible index.<br />
This simply means that even if you are not using the index to execute query, two leaf pages (and all the tree branches to reach them) will end up being fetched from disk into the cache &#8211; wasting both I/O cycles and memory.</p>
<p>There&#8217;s also quite interesting paradox at this &#8211; in some cases, more similar other indexes are, more waste they create because of rows-in-range checks. If a table has indexes on (a,b,c) and (a,b,d), query for (a,b,d) will be best satisfied by (a,b,d) index, but will evaluate range sizes for (a,b). If the first index were (a,c,b), it would be only able to check head and tail of (a) &#8211; so way less B-Tree positions would be cached in memory for the check. This makes better indexing sometimes fare worse than what they&#8217;re worth in benchmarks (assuming that people do I/O-heavy benchmarking :)</p>
<p>The easy way out is using FORCE INDEX. It will not do the index evaluation &#8211; and no B-Tree dives on unneeded index.</p>
<p>In my edge case testing with real data and skewed access pattern hitting a second index during &#8216;statistics&#8217; phase has increased execution time by 70%, number of I/Os done by 75%, number of entrances into buffer pool by 31% and bloated buffer pool with data I didn&#8217;t need for read workload.</p>
<p>For some queries like &#8220;newest 10 entries&#8221; this will actually waste some space preheating blocks from the other end of the range that will never be shown &#8211; there will definitely be a B-Tree leaf page in buffer pool with edits from few years ago because of RIR. Unfortunately, the only MySQL-side solution for this is HANDLER interface (or probably HandlerSocket) &#8211; but it doesn&#8217;t make using FORCE INDEX not worth it &#8211; it just pushes towards making FORCE INDEX be much more forceful.</p>
<p>So, use the FORCE, Luke :)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/834/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=834&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2011/01/27/a-case-for-force-index/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
		<item>
		<title>random poking</title>
		<link>http://dom.as/2010/11/08/random-poking/</link>
		<comments>http://dom.as/2010/11/08/random-poking/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 04:55:26 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[innodb]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[sysbench]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=811</guid>
		<description><![CDATA[These are some of my notes from some sysbench in-memory r/o testing in past day or so: At &#8216;fetch data by primary key&#8217; benchmark with separate read snapshots at each statement, MySQL shines until ~200 concurrent threads, then performance starts &#8230; <a href="http://dom.as/2010/11/08/random-poking/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=811&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>These are some of my notes from some sysbench in-memory r/o testing in past day or so:</p>
<ul>
<li>At &#8216;fetch data by primary key&#8217; benchmark with separate read snapshots at each statement, MySQL <a href='https://spreadsheets.google.com/pub?key=0AtHDNfVx0WNhdG13QkgwUXZITTM2UGtjRHU1VkRVbkE&amp;hl=en&amp;gid=4'>shines</a> until ~200 concurrent threads, then performance starts dropping slightly faster than one would want, I think mostly from <a href='http://bugs.mysql.com/bug.php?id=58037'>table cache LOCK_open contention</a></li>
<li>auto-commit cost (establishing read snapshot per statement) for SELECTs is ~10% for MySQL, but for PG it can be +50% in plain SQL mode and +130% (!!!!!!!) when using prepared statements (this can be seen in a <a href='https://spreadsheets.google.com/pub?key=0AtHDNfVx0WNhdG13QkgwUXZITTM2UGtjRHU1VkRVbkE&amp;hl=en&amp;gid=5'>graph</a> &#8211; obviously the global lock PG has during this operation is held for too long and maybe is too costly to acquire.)</li>
<li>Some benchmarks went up by 10% when using jemalloc</li>
<li>MySQL could accept 10x more connections per second than PG (15000 vs 1500)</li>
<li>Most confusing behavior MySQL exhibited was at 100-record range scans in PK order:
<ul>
<li>At innodb_thread_concurrency=0 it did around 70k range reads, both fetching data and aggregation (SUM())</li>
<li>At innodb_thread_concurrency&gt;0 it did only 10k range reads returning data but still was able to do 70k aggregations/s</li>
<li>PG was doing ~35k ops/s at that test</li>
</ul>
<p>It seems that at least for systems that do lots of range scans (or joins) I guess, managed concurrency kills performance entirely due to giving up tickets too often, need to review it more (Update: it seems that offending stack is ha_release_temporary_latches being called way too early in the select_send::send_data()).
</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/811/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/811/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/811/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/811/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/811/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/811/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/811/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/811/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/811/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/811/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/811/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/811/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/811/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/811/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=811&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2010/11/08/random-poking/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
		<item>
		<title>on performance stalls</title>
		<link>http://dom.as/2010/09/22/on-performance-stalls/</link>
		<comments>http://dom.as/2010/09/22/on-performance-stalls/#comments</comments>
		<pubDate>Wed, 22 Sep 2010 13:22:43 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[facebook]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[innodb]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[pmp]]></category>
		<category><![CDATA[stalls]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=795</guid>
		<description><![CDATA[We quite often say, that benchmark performance is usually different from real world performance &#8211; so performance engineering usually has to cover both &#8211; benchmarks allow to understand sustained performance bottlenecks, and real world analysis usually concentrates on something what &#8230; <a href="http://dom.as/2010/09/22/on-performance-stalls/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=795&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We quite often say, that benchmark performance is usually different from real world performance &#8211; so performance engineering usually has to cover both &#8211; benchmarks allow to understand sustained performance bottlenecks, and real world analysis usually concentrates on something what would be considered &#8216;exceptional&#8217; and not important in benchmarks &#8211; stalls of various kind. They are extremely important, as the state when our performance is lowest is the state of performance we provide to our platform users.</p>
<p>On a machine that is doing 5000qps, stalling for 100ms means that 500 queries were not served as fast as they could, or even hit application timeouts or exceptional MySQL conditions (like <a href='http://bugs.mysql.com/bug.php?id=26590'>1023</a> transaction limit). Of course, stalling for a second means 5000 queries were not served in time&#8230;</p>
<p>We have multiple methods to approach this &#8211; one is our &#8216;dogpiled&#8217; framework &#8211; an agent doing status polling every second and reporting information about I/O state, MySQL/InnoDB statuses, processlists, etc &#8211; so we see the scope of stalls in our environment. We try to maintain the threshold between complete information overload and something that reveals problems &#8211; so it is always balancing act, especially with great work done by engineering team :)</p>
<p>Other approach, usually led to by dogpiles information, is auto-<a href='http://poormansprofiler.org'>PMP</a> &#8211; high-frequency status polling combined with gdb invocations, that allow us to jump into the process whenever we notice something weird is going on. We have some extensions to how we use PMP &#8211; but thats worth another post.</p>
<p>Issues we do find out that harm us most in production environments are ones that are quite often discarded as either &#8220;this never happens&#8221; or &#8220;get better hardware&#8221; or &#8220;your application is wrong&#8221;. Unfortunately, that happens, we do have thousands of machines that aren&#8217;t free and our application demands are our application demands :)</p>
<p>Few examples:</p>
<ul>
<li><a href='http://bugs.mysql.com/bug.php?id=56696'>TRUNCATE stalls the server</a> (oh well, <a href='http://bugs.mysql.com/bug.php?id=41158'>DROP TABLE too</a>) &#8211; in this case, truncating a table grabs dictionary mutex, other transaction blocks while holding LOCK_open, everything else stops. Though truncating is supposed to be fast operation, it has to unlink (delete) a file, and with large files such operation isn&#8217;t really instant on any filesystem. Even if one deletes all the data before truncating, file is still on the filesystem.</li>
<li><a href='http://bugs.mysql.com/bug.php?id=56433'>Extending data files stalls the server</a> &#8211; when a data file is being extended, global mutex is held, which blocks all I/Os (with limited concurrency that is full server stall). Somewhat more impressive with file-per-table. This is the major reason for mini-stalls at the moment &#8211; on machines that grow at gigabytes-a-day rate this is being hit quite often.</li>
<li><a href='http://bugs.mysql.com/bug.php?id=56340'>Updating table statistics stalls the server</a> &#8211; we hit this with high-performance task tracking machines, row churn there is quite amazing, and dictionary statistics are reread more often than one would expect. Updating statistics means locking the table while doing random reads from disk. Once major workload is hitting that table, it quickly escalates to full server stall</li>
<li><a href='http://bugs.mysql.com/bug.php?id=55004'>Fuzzy checkpoint stalls the server</a> &#8211; this is one of biggest issues outstanding in stock MySQL &#8211; though one would expect that &#8220;fuzzy checkpoint&#8221; that uses async background threads is nonblocking, actually all writes during it will stall, taking all concurrency slots and leading to a server stall. Mark&#8217;s fix was just doing this work in background thread.</li>
<li>(no bug filed on this yet) &#8211; Purge stalls the server &#8211; purge holds dictionary lock while doing random reads from disk, with table stall leading to server stall.</li>
</ul>
<p>There&#8217;re more issues (mostly related to heavier in-memory activities of the server), but these ones are most obvious ones &#8211; where single I/O request done is escalated to table or instance lockup, where no other work is done. Our machines have multiple disks, multiple CPUs and can support multiple SQL queries being executed at once, so any of these lockups effectively limit our available performance or damage the quality of service we can provide.</p>
<p>On the upside, my colleagues are absolutely amazing and I&#8217;m sure that we will have all these issues fixed in our deployment in near future, as well as everyone will be able to pick that up via <a href='https://code.launchpad.net/mysqlatfacebook'>mysqlatfacebook</a> branch.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/795/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/795/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/795/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/795/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/795/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/795/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/795/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/795/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/795/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/795/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/795/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/795/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/795/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/795/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=795&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2010/09/22/on-performance-stalls/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
		<item>
		<title>Postgres kernel regressions</title>
		<link>http://dom.as/2010/09/13/postgres-kernel-regression/</link>
		<comments>http://dom.as/2010/09/13/postgres-kernel-regression/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 14:30:25 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[postgres]]></category>

		<guid isPermaLink="false">http://mituzas.lt/?p=791</guid>
		<description><![CDATA[While Mark was looking at MongoDB, I was playing comparing various aspects of MySQL and Postgres performance. Certain PG performance numbers I saw (40kqps vs 110kqps from MySQL) made me really upset, so I ended up discussing with people at &#8230; <a href="http://dom.as/2010/09/13/postgres-kernel-regression/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=791&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While Mark <a href='http://mysqlha.blogspot.com/2010/09/mysql-versus-mongodb-yet-another-silly.html'>was looking at</a> MongoDB, I was playing comparing various aspects of MySQL and Postgres performance. Certain PG performance numbers I saw (40kqps vs 110kqps from MySQL) made me really upset, so I ended up discussing with people at #postgresql &#8211; and started comparing various versions/configurations/machines/etc.</p>
<p>Apparently 2.6.32 kernel, which is in Ubuntu 10.04 LTS (Lucid Lynx) and is also basis for future RHEL6 kernel has nearly 20% performance degradation for PG (though not for MySQL, phew) &#8211; and apparently it was news to their community (I have <a href='http://archives.postgresql.org/pgsql-hackers/2010-09/msg00627.php'>started an email thread</a>, will see where it goes).</p>
<p>While I was doing my research, of course I could observe plenty of gems of wisdom:</p>
<blockquote><p>
&lt;davidfetter&gt; domas, well, as tom lane once said, there&#8217;s no limit to how quickly you can get an answer if it doesn&#8217;t have to be correct
</p></blockquote>
<p>And an hour later:</p>
<blockquote><p>
&lt;rawtaz&gt; are you one of those mysql lovers?<br />
&#8230;<br />
&lt;dim&gt; nobody wants performance at the price of correctness, right?<br />
 &lt;dim&gt; as Tom said, I can be as quick as you want as providing an answer if you don&#8217;t want it to be correct (hint: 42.)
</p></blockquote>
<p>Apparently chasing these performance variations is&#8230;</p>
<blockquote><p>
&lt;Snow-Man&gt; tbh, I&#8217;m of the opinion that we&#8217;re losing the forest for the trees.
</p></blockquote>
<p>Can&#8217;t say that all of them were encouraging:</p>
<blockquote><p>
&lt;sterncera&gt; If you can&#8217;t be bothered to subscribe to -hackers, maybe you shouldn&#8217;t be mailing it
</p></blockquote>
<p>Special thanks goes to <i>mastermind</i>, who not only didn&#8217;t lose his temper, but stayed focused on the topic and resisted my trolling :-) I really want PG to be greatly performing database (and I&#8217;ve seen some great numbers from it), but the amazing amount of ignorance and animosity they have against MySQL makes it somewhat complicated there though :(</p>
<p>P.S. Now all benchmarks I did are tainted and will need full rerun&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/791/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/791/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/791/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/791/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/791/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/791/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/791/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/791/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/791/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/791/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/791/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/791/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/791/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/791/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=791&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2010/09/13/postgres-kernel-regression/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
		<item>
		<title>Opening tables v2!</title>
		<link>http://dom.as/2010/02/26/opening-tables-v2/</link>
		<comments>http://dom.as/2010/02/26/opening-tables-v2/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 17:04:51 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[mutex]]></category>
		<category><![CDATA[performance]]></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 &#8230; <a href="http://dom.as/2010/02/26/opening-tables-v2/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=725&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></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 title="Opening tables!" href="http://dom.as/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>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/725/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=725&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2010/02/26/opening-tables-v2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
		<item>
		<title>Crash recovery, again</title>
		<link>http://dom.as/2009/12/08/crash-recovery-again/</link>
		<comments>http://dom.as/2009/12/08/crash-recovery-again/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 15:29:30 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[crash]]></category>
		<category><![CDATA[innodb]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[recovery]]></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 &#8230; <a href="http://dom.as/2009/12/08/crash-recovery-again/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=658&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></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://dom.as/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>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/658/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/658/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/658/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/658/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/658/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/658/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/658/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/658/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/658/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/658/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/658/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/658/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/658/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/658/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=658&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2009/12/08/crash-recovery-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
		<item>
		<title>again, on benchmarks</title>
		<link>http://dom.as/2009/11/19/again-on-benchmarks/</link>
		<comments>http://dom.as/2009/11/19/again-on-benchmarks/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 20:03:34 +0000</pubDate>
		<dc:creator>Domas Mituzas</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[profiling]]></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 &#8230; <a href="http://dom.as/2009/11/19/again-on-benchmarks/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=645&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></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://dom.as/2009/06/30/on-file-system-benchmarks/">ranted</a> at benchmarks before, and will continue doing so.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/domasmituzas.wordpress.com/645/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/domasmituzas.wordpress.com/645/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/domasmituzas.wordpress.com/645/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/domasmituzas.wordpress.com/645/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/domasmituzas.wordpress.com/645/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/domasmituzas.wordpress.com/645/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/domasmituzas.wordpress.com/645/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/domasmituzas.wordpress.com/645/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/domasmituzas.wordpress.com/645/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/domasmituzas.wordpress.com/645/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/domasmituzas.wordpress.com/645/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/domasmituzas.wordpress.com/645/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/domasmituzas.wordpress.com/645/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/domasmituzas.wordpress.com/645/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dom.as&amp;blog=190075&amp;post=645&amp;subd=domasmituzas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dom.as/2009/11/19/again-on-benchmarks/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c660a6eb3a4005232acb111303bef12c?s=96&#38;d=http%3A%2F%2Fs0.wp.com%2Fi%2Fmu.gif&#38;r=G" medium="image">
			<media:title type="html">domasmituzas</media:title>
		</media:content>
	</item>
	</channel>
</rss>
