<?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>MySQL Performance Blog &#187; lamp</title>
	<atom:link href="http://www.mysqlperformanceblog.com/category/lamp/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlperformanceblog.com</link>
	<description>Everything about MySQL Performance</description>
	<lastBuildDate>Sat, 21 Nov 2009 03:11:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Looking at Redis</title>
		<link>http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 17:48:02 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[lamp]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=1063</guid>
		<description><![CDATA[Recently I had a chance to take a look at Redis project, which is semi-persistent in memory database with idea somethat similar to memcache but richer feature set. 
Redis has simple single process event driven design, which means it does not have to deal with any locks which is performance killer for a lot of [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I had a chance to take a look at <a href="http://code.google.com/p/redis/">Redis</a> project, which is semi-persistent in memory database with idea somethat similar to memcache but richer feature set. </p>
<p>Redis has simple single process event driven design, which means it does not have to deal with any locks which is performance killer for a lot of applications. This however limits it scalability to single core. Still with 100K+ operations a second this single core performance will be good enough for many applications.  Also nothing stops you from running many Redis instance on single server to get advantage of multiple cores.</p>
<p>I call Redis  semi-persistent  because it does not store the data on disk immediately but rather dumps its all database every so often &#8211; you have a choice of configuring time and number of updates between database dumps.  Because dump  is basically serial write Redis  does not an expensive IO subsystem. Also because this dump is background it does not affect read/write performance to the database which is in memory.  In the tests I&#8217;ve done I&#8217;ve seen Redis doing writes some 4MB/sec  for probably 50% of test duration where Innodb had to write 50MB/sec  for about third of throughput and doing a lot of random IO as it was doing it.   This is among other things because Innodb has to flush full 16K pages while doing flush.</p>
<p>The background flush in Redis is designed the following way &#8211;  Redis process forks  and justs dumps the database it has in the background.  Unix copy on write  takes care of getting another copy of pages as they are modified.  This keeps overhead rather low.   The database is dumped in temporary file which is renamed only after fsync  which means if you crash during the dump you simply discard partial file.</p>
<p>I also liked full pipelining support in the protocol &#8211;  you can send multiple commands at once &#8211; any commands and redis server will process them in order and returns results to you.  This not only allows for multi-get and multi-set but any of batches of commands being submitted.  The API support for this is relatively week but the features are there.</p>
<p>When it comes to data types &#8211; Redis supports  simple key-value storage just as memcache but it also adds support for Lists, which are similar to the linked list data type you would have as well as sets which allow to store sets of strings with support of various set operations.</p>
<p>I kind of miss support for something like associative array/hash/map  in the data types but I guess there is nothing in architecture which would stop it from being added later.</p>
<p>Redis also has support for &#8220;databases&#8221;  which are basically key spaces inside the server.  This should allow for using server by different applications, different versions, testing or some other features.  Though you&#8217;ve got to be careful with these &#8211; there is only simple per instance password based authentication in place, so if application can talk to the instance it can access all databases.</p>
<p>I am also a bit surprised why databases are numbered instead of named.   Naming the databases would make it more simple to avoid unwanted conflicts etc.</p>
<p>Redis also supports master/slave replication out of the box and it is extremely simple.  You just specify from which node to replicate and this is it. It is even more simple than with MySQL as you do not need to deal with snapshot or binary log position.   Replication is asynchronous and low overhead &#8211; redis will perform the database dump and store the commands on the data since the start of the process. Slave can get the data (which is basically set of commands to populate database itself) and when get the data from the master as it comes.   I did not benchmark the replication capacity but I&#8217;d expect it to be close to 100K of writes/sec the single instance can handle. </p>
<p>The benchmarks I&#8217;ve done were for applications which is very update intensive with updates being pretty much random single row updates which are hard to batch.   With MySQL/Innodb I got server being able to handle some <strong>30.000 updates/sec</strong> on 16 core server with  replication being able to handle <strong>10.000 updates/sec</strong>.  This was using about 5 cores so you could probably get 4 MySQL instances on this server and get up to 100K updates/sec with up to 40K updates/sec  being able to replicate.  </p>
<p>With Redis  I got about 3 times more updates/sec &#8211; close to <strong>100.000 updates/sec</strong> with about 1.5 core being used.   I have not tried running multiple instances and I&#8217;m not sure the network and TCP stack would scale linearly in this case but anyway we&#8217;re speaking about hundreds of thousands of updates/sec.</p>
<p>I think Redis can be great piece of architecture for number of applications. You can use it as the database or as cache (it supports data expiration too)</p>
<p>I have not benchmarked it against memcache in terms of performance and memory usage. This may be another project to look at.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/#comments">21 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/&amp;title=Looking at Redis" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/&amp;title=Looking at Redis" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/&amp;title=Looking at Redis" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/&amp;T=Looking at Redis" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/&amp;title=Looking at Redis" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/08/27/looking-at-redis/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Worse than DDOS</title>
		<link>http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/</link>
		<comments>http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 06:55:19 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[lamp]]></category>
		<category><![CDATA[production]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=470</guid>
		<description><![CDATA[Today I worked on rather interesting customer problem.  Site was subject what was considered DDOS and solution was implemented to protect from it.   However in addition to banning the intruders IPs it banned IPs of web services which were very actively used by the application which caused even worse problems by consuming [...]]]></description>
			<content:encoded><![CDATA[<p>Today I worked on rather interesting customer problem.  Site was subject what was considered DDOS and solution was implemented to protect from it.   However in addition to banning the intruders IPs it banned IPs of web services which were very actively used by the application which caused even worse problems by consuming all apache slots which were allocated to the problem.  Here are couple of interesting lessons one can learn from it.</p>
<p><strong>Implement proper error control</strong>  In reality it took some time to find what was the issue because there was no error reporting for situation of unavailable web services.  If log would be flooded with messages about web services being unavailable it would be much easier to find.</p>
<p><strong>User Curl</strong>  PHP Has a lot of functions which can accept URL as parameter and just fetch the data transparently for you. They however do not give you good error control and timeout management compared to curl module.  Use that when possible it is easy. You can implement your own class to fetch required URL with single call while having all needed timeout handling and reporting to match your application needs.   If you&#8217;re using PHP functions make sure <strong>default_socket_timeout</strong> has proper value or set it per session.</p>
<p><strong>Set Curl Timeouts</strong>  Set both <strong>TIMEOUT</strong> and <strong>CONNECT_TIMEOUT</strong> as these apply to different connection stages and just setting timeout is not enough.</p>
<p><strong>Beware of PHP sessions &#8220;files&#8221; handler </strong>   I already <a href="http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/">wrote</a> about this topic, but when troubleshooting this all takes another angle.   Default file handler means file gets locked  while PHP request is being served.   In this case because of network stall request could be taking 100+ seconds.  Users are inpatient and do not wait so long pressing reload multiple times&#8230; which just adds to the list of users waiting on session file lock.   This not only makes apache slots consumed at much higher pace but makes it harder to find what exactly is causing the lock because most of offending processes you can find from apache &#8220;server-status&#8221; will be just waiting on file to be unlocked.    I used &#8220;gdb&#8221; to connect to the process showing high number of seconds since start finding where it is stuck.  If it is somewhere in curl module (or mysql &#8211; waiting on long query to come back) &#8211; this is our query if it is waiting on the session file lock we can get that file and  use <strong>fuser</strong> to see what other processes are using that files &#8211; these would be either waiting on locks or owning the lock and so one of them is the process we&#8217;re looking for.   Things are much easier with say memcached session storage &#8211;  this does not cause any locks for parallel session use so only the process which actually stalls waiting on external resource will show high number of seconds since request start. </p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/#comments">5 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/&amp;title=Worse than DDOS" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/&amp;title=Worse than DDOS" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/&amp;title=Worse than DDOS" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/&amp;T=Worse than DDOS" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/&amp;title=Worse than DDOS" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2008/08/18/worse-than-ddos/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PHP vs. BIGINT vs. float conversion caveat</title>
		<link>http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/</link>
		<comments>http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/#comments</comments>
		<pubDate>Thu, 10 Jan 2008 23:59:02 +0000</pubDate>
		<dc:creator>shodan</dc:creator>
				<category><![CDATA[bugs]]></category>
		<category><![CDATA[lamp]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/</guid>
		<description><![CDATA[Sometimes you need to work with big numbers in PHP (gulp). For example, sometimes 32-bit identifiers are not enough and you have to use BIGINT 64-bit ids; e.g. if you are encoding additional information like the server ID into high bits of the ID.
I had already written about the mess that 64-bit integers are in [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you need to work with big numbers in PHP (gulp). For example, sometimes 32-bit identifiers are not enough and you have to use BIGINT 64-bit ids; e.g. if you are encoding additional information like the server ID into high bits of the ID.</p>
<p>I had <a href="http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/">already written</a> about the mess that 64-bit integers are in PHP. But if the numbers you use do not cover 64-bit range fully, floats might save the day. The trick is that PHP floats are in fact doubles, i.e. double-precision 64-bit numbers. They have 52 bits for mantissa, and integer values up to 2^53-1 can be stored exactly. So if you're using up to 53 bits, you're OK with floats.</p>
<p>However, there's a conversion caveat you should be aware of.</p>
<p>On different systems, <b>float is converted to string differently</b>. (I spent a bit of time fighting with it today.) Consider the following script:</p>
<div class="igBar"><span id="lcode-6"><a href="#" onclick="javascript:showPlainTxt('code-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-6">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;?php</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">$f = <span style="color:#800000;color:#800000;">65536</span>*<span style="color:#800000;color:#800000;">65536</span>*<span style="color:#800000;color:#800000;">65536</span>*<span style="color:#800000;color:#800000;">4</span>; <span style="color:#FF9933; font-style:italic;">// 2^50</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">$f += <span style="color:#800000;color:#800000;">1</span>; <span style="color:#FF9933; font-style:italic;">// 2^50+1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">$s1 = <span style="color:#CC0000;">"$f"</span>; <span style="color:#FF9933; font-style:italic;">// the usual way</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">$s2 = sprintf <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0000;">"%.0f"</span>, $f <span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// the &quot;right&quot; way</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">print <span style="color:#CC0000;">"s1=$s1 s2=$s2<span style="color:#000099; font-weight:bold;">\n</span>"</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">?&gt; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>It prints the following (normally expected) output on x64 box running Linux with PHP 5.1.6 or 5.2.2, and also with PHP 4.4.2 on SPARC64 under NetBSD 3.0:</p>
<div class="igBar"><span id="lcode-7"><a href="#" onclick="javascript:showPlainTxt('code-7'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-7">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">s1=<span style="color:#800000;color:#800000;">1125899906842625</span> s2=<span style="color:#800000;color:#800000;">1125899906842625</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>However 32-bit FreeBSD with PHP 4.4.7 produces different results:</p>
<div class="igBar"><span id="lcode-8"><a href="#" onclick="javascript:showPlainTxt('code-8'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-8">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">s1=<span style="color:#800000;color:#800000;">1</span>.1258999068426E+<span style="color:#800000;color:#800000;">15</span> s2=<span style="color:#800000;color:#800000;">1125899906842625</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The same 32-bit FreeBSD box with PHP 5.2.5 starts to emit all digits but still incorrectly:</p>
<div class="igBar"><span id="lcode-9"><a href="#" onclick="javascript:showPlainTxt('code-9'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-9">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">s1=<span style="color:#800000;color:#800000;">1125899906842600</span> s2=<span style="color:#800000;color:#800000;">1125899906842625</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>And PHP 5.2.2 on Windows produces yet another variant:</p>
<div class="igBar"><span id="lcode-10"><a href="#" onclick="javascript:showPlainTxt('code-10'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-10">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">s1=<span style="color:#800000;color:#800000;">1125899906840000</span> s2=<span style="color:#800000;color:#800000;">1125899906842625</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>As you can see float to string conversion is <b>not</b> portable across systems and PHP versions. So if you're handling large numbers stored as float (especially on 32-bit systems where 32-bit int overflow will implicitly convert to float) and getting strange bugs, remember that string conversion might let you down. sprintf(), on the other hand, is always a friend when it comes to fixing PHP "subtleties" in numeric value handling: it can be used to workaround signed vs. unsigned int issues; it helps with float formatting; always a saviour.</p>
<p><b>UPDATE:</b> as Jakub Vrana pointed out in the comments (thanks!), it's the "precision" option set from php.ini which affects the conversion. I've played with it a bit; the compiled-in and php.ini-dist values seem to vary across architectures and versions, but setting precision=16 (enough to hold 2^53 in decimal without sign) helped in <b>all</b> cases.</p>
<p>However at the moment the option is neither mentioned in the online documentation, nor explained clearly in php.ini. So this adds another fixing route (ie. you could just set higher precision); but the caveat is still there.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by shodan |
      <a href="http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/#comments">18 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/&amp;title=PHP vs. BIGINT vs. float conversion caveat" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/&amp;title=PHP vs. BIGINT vs. float conversion caveat" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/&amp;title=PHP vs. BIGINT vs. float conversion caveat" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/&amp;T=PHP vs. BIGINT vs. float conversion caveat" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/&amp;title=PHP vs. BIGINT vs. float conversion caveat" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2008/01/10/php-vs-bigint-vs-float-conversion-caveat/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Pitfall of proxying HTTP requests through Lighttpd</title>
		<link>http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/</link>
		<comments>http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/#comments</comments>
		<pubDate>Fri, 23 Nov 2007 00:04:28 +0000</pubDate>
		<dc:creator>Maciej Dobrzanski</dc:creator>
				<category><![CDATA[lamp]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/</guid>
		<description><![CDATA[Recently I had a case with a web server farm where a random node went down every few minutes. I don't mean any of them rebooted except once or twice, but rather they were slowing down so much that practically stopped serving any requests and were being pulled out from the LVS cluster. The traffic [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I had a case with a web server farm where a random node went down every few minutes. I don't mean any of them rebooted except once or twice, but rather they were slowing down so much that practically stopped serving any requests and were being pulled out from the LVS cluster. The traffic was not any different than usual, all other elements of the system worked perfectly fine (e.g. databases, storage), no one started any backup in the middle of the day as it happens sometimes... so what was happening?</p>
<p>First I am going to describe the setup a little bit. As I already mentioned it was about web servers. Each of them was running Lighttpd that handled the requests coming from the internet. It was configured however only to serve static content, such as images. The requests asking for PHP files were passed down with proxy module to Apache listening on another TCP port.</p>
<p>And so I started investigating the problem. As it turned out the systems were slowing down because <code>lighttpd</code> process grew to a few gigabytes eating the entire memory which caused system to start swapping heavily. This usually means death to a busy on-line system. Initially I thought about hitting some Lighttpd bug as nothing else seemed wrong, but after a short while I remembered one thing that can cause such behavior. If you use it as a proxy, it will need to buffer the entire response from the backend server before sending to the client. And indeed I started browsing Apache access log and found entries similar to this appearing every few minutes:</p>
<div class="igBar"><span id="lcode-12"><a href="#" onclick="javascript:showPlainTxt('code-12'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-12">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#800000;color:#800000;">127</span>.<span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">1</span> - - <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#800000;color:#800000;">15</span>/Nov/<span style="color:#800000;color:#800000;">2007</span>:<span style="color:#800000;color:#800000;">08</span>:<span style="color:#800000;color:#800000;">10</span>:<span style="color:#800000;color:#800000;">56</span> -<span style="color:#800000;color:#800000;">0500</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#CC0000;">"GET /php/call.php?page=somearg HTTP/1.0"</span> <span style="color:#800000;color:#800000;">200</span> <span style="color:#800000;color:#800000;">5105062572</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Apparently some bug in PHP code with a loop having far too many iterations and even though Apache and PHP handled it without much hassle, Lighttpd kept allocating memory to fit the entire response into the buffer and caused all that mess.</p>
<p>Although this was an extreme case, it is easy to imagine the situation where the problems will appear with much smaller data being sent through Lighttpd proxy. For example with a PHP script for handling larger file downloads which gets many concurrent requests.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Maciej Dobrzanski |
      <a href="http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/#comments">10 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/&amp;title=Pitfall of proxying HTTP requests through Lighttpd" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/&amp;title=Pitfall of proxying HTTP requests through Lighttpd" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/&amp;title=Pitfall of proxying HTTP requests through Lighttpd" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/&amp;T=Pitfall of proxying HTTP requests through Lighttpd" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/&amp;title=Pitfall of proxying HTTP requests through Lighttpd" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2007/11/22/pitfall-of-proxying-requests-with-lighttpd/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Sphinx:  Going Beyond full text search</title>
		<link>http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/</link>
		<comments>http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/#comments</comments>
		<pubDate>Tue, 24 Jul 2007 03:32:10 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[lamp]]></category>
		<category><![CDATA[production]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/</guid>
		<description><![CDATA[I've already wrote a few times about various projects using Sphinx with MySQL for scalable Full Text Search applications.   For example on BoardReader we're using this combination to build search against over 1 billion of forum posts totaling over 1.5TB of data handling hundreds of thousands of search queries per day.
The count of [...]]]></description>
			<content:encoded><![CDATA[<p>I've already wrote a few times about various projects using <a href="http://www.sphinxsearch.com">Sphinx</a> with MySQL for scalable Full Text Search applications.   For example on <a href="http://www.boardreader.com">BoardReader</a> we're using this combination to build search against over 1 billion of forum posts totaling over 1.5TB of data handling hundreds of thousands of search queries per day.</p>
<p>The count of forum posts being large, is however not the largest we've got to deal in the project -  number of links originating from forum posts is a bit larger number.   </p>
<p>The task we had for links is to be able to search for links pointing to <a href="http://boardreader.com/linkinfo/mysql.com">given web site</a> as well.    The challenge in this case is we do not only want to match links directed to "mysql.com" but links to "www.mysql.com" or "dev.mysql.com/download/"  as well as they are all considered to belong to mysql.com domain, while searching for "dev.mysql.com/download"" will only match dev.mysql.com domain  and files within /download/ directory. </p>
<p>Initially we implemented it in MySQL using partitioning by domain which link was pointing to.  So "mysql.com" links were stored in one table group  and "google.co.uk" on another.   We still had serious challenges however -  as each applies to many search URLS,<br />
such as "dev.mysql.com/download/mysql-5.1.html" would  match "mysql.com", "dev.mysql.com",  "dev.mysql.com/download/" and<br />
"dev.mysql.com/download/mysql-5.1.html"   we could not use   link=const where clause but had to use   link like "prefix%"  which means index could not be used to get 20 last links and  filesort over millions of links we had to youtube.com wikipedia.org and other top domains was extremely slow.   Not to mention  counting number of links (and number number of distinct forum sites) pointing to the given URL or graphs showing number of links per day.  To fight this problem we had to restrict number of days we allow to cover based on the amount of links to the domain... but for some top domains it was slow even with just 3 days worth of data.   </p>
<p>You might point out if we had    link_date between X and Y and  link like "prefix%" kind of where clause we would not be able to use index past link_date part,  it is true so we had to use  link_date  in (
<list of dates>) and link like "prefix%" which allows to use both keyparts which is much better but not good enough.</p>
<p>Caching is not good enough in such case as we do not want a single user to wait for minutes. large variety of problematic search urls does not allow to use pre-caching not to mention general load on server such batch processing would put. </p>
<p>The first alternative to this approach was to store duplicate data storing link to "dev.mysql.com/download/mysql-5.1.html" as links to 4  url prefixes I mentioned above.    Unfortunately this would blow up data stored quite significantly, requiring in average of 6 rows for each link and it does not solve all the problems - result counting and number of distinct sites were still pretty slow and we did not want to go into creating all this data as summary tables. </p>
<p>Instead we decided to use Sphinx for this kind of task which proved to be extremely good idea.   We converted all URLs to search keywords and  now these 6 rows become simply  one row in sphinx index with 6 "keywords" - specially crafter strings which corresponded to the URLs.    Of course we did not store these in the table but instead used UDF to convert URL to list of "keywords"  on the fly.  </p>
<p>As results we now can pull up results even for <a href="http://boardreader.com/linkinfo/youtube.com">youtube.com</a> for fractions of the second and we could show 3 months worth of data for any URLs.  (We could use longer time span but we did not have enough memory for Sphinx attribute storage).   It is especially great as there is still room for optimization - Sphinx stores word positions in the index, while we do not need them in this case as we're doing kind of "boolean full text search".  Plus we can make index built sorted by timestamp which would allow to same on sorting which is now still happening. </p>
<p>Using Sphinx such non-traditional way required implementing some features more traditional for SQL databases rather than full text search applications.   Group By was added to  Sphinx so we could search number of matches per day, or number of matches per language.  </p>
<p>For <a href="http://boardreader.com/domain/wikipedia.org">Domain Profile</a> we've got to use even more of those features such as counting number of distinct sites pointing to the given url or domain etc.   Honestly this is where we cheated a bit and distinct number is bit approximate for large numbers but it still works really well for our needs. </p>
<p>Sure we could use summary tables for domains but it would be a lot of work and raver inflexible if we would like to add some more features and take a lot of resources to update or periodically build for millions of domains. </p>
<p>As this part worked pretty well we also decided to use Sphinx for other part of the web site - <a href="http://boardreader.com/sp/Nintendo_NSider_Forums_9848.html">Forum Site Profile</a>.  This uses some pre-generated data such as number of posts in total for forum or in thread but most of other stuff is built with Sphinx.    This also uses fair amount of tricks using fake full text search to retrieve all posts from given web site or forum from the global sphinx index. </p>
<p>So in general we find parallel processing using sphinx pretty good solution for many data crunching needs especially when lack of parallel abilities in MySQL makes its use rather inconvenient and pre-generating data is inconvenient or impossible. </p>
<p>If you're attending OSCON 2007 and would like to learn more about Sphinx we have a <a href="http://conferences.oreillynet.com/cs/os2007/view/e_sess/14798">BOF</a> on Thursday to talk on the topic.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/#comments">15 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/&amp;title=Sphinx:  Going Beyond full text search" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/&amp;title=Sphinx:  Going Beyond full text search" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/&amp;title=Sphinx:  Going Beyond full text search" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/&amp;T=Sphinx:  Going Beyond full text search" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/&amp;title=Sphinx:  Going Beyond full text search" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2007/07/23/sphinx-going-beyond-full-text-search/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>PHP  Large result sets and summary tables.</title>
		<link>http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/</link>
		<comments>http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/#comments</comments>
		<pubDate>Fri, 06 Jul 2007 19:12:27 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[lamp]]></category>
		<category><![CDATA[production]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/</guid>
		<description><![CDATA[We're working with web site preparing for massive growth.    To make sure it handles large data sets as part of the process we work on generation test database of significant size as  testing your application on table with 1000 rows may well give you very dangerous false sense of security. 
One [...]]]></description>
			<content:encoded><![CDATA[<p>We're working with web site preparing for massive growth.    To make sure it handles large data sets as part of the process we work on generation test database of significant size as  testing your application on table with 1000 rows may well give you very dangerous false sense of security. </p>
<p>One of the process web site had was creating of summary tables which was done by executing some huge group by query, doing some stuff with results and then populating tables.  This all worked well for small tables... but not for larger ones. </p>
<p>First problem was PHP script generating the table took 10GB of RAM and was swapping development server which had just 4GB of Ram (and plenty of swap space) like crazy.   Why ?  Because by default <strong>mysql_query</strong> uses <strong>mysql_store_result</strong> C library call and buffers all result set in the process memory.  Not good if there are over 50 millions of rows.   Note  this limit is not controlled by <strong>memory_limit</strong> PHP config variable because that only controls memory which passes via PHP memory management which does not apply to MySQL result set. </p>
<p>OK there is "easy" fix for this problem,  you can use <strong>mysql_unbuffered_query</strong> instead and mysqli and PDO have their own way to reach similar behavior. This call users underlying <strong>mysql_use_result</strong>  API call which does not store all result set in memory but instead streams it from the server, fetching in blocks. There are some limits as you can't use mysql_num_rows() and mysql_data_seek() if you use this method but this is told in PHP manual and so easy to catch.   There are however more differences which may cause things breakage </p>
<ol>
<li> <strong>Table Locks</strong>  - Table locks are not cleared until you fetch whole result set if you're reading from tables directly (if you do not have "using temporary" in EXPLAIN) this was not issue for given case as GROUP BY in question required temporary table plus it was test system anyway.    The workaround for this one is to use SQL_BUFFER_RESULT hint if you need to release table locks early.  It comes at cost of creating temporary table though which can be quite high. </li>
<li> <strong>Sharing connection no more works</strong>   If you use buffered query you can use same connection to run other queries, ie INSERTs and UPDATEs while you traverse with data.  Not with unbuffered query because connection is still busy. </li>
<li> <strong>Need more error checking </strong> If you use buffered query the only real call you can get errors is when you run <strong>mysql_query </strong>,  <strong>mysql_fetch_row</strong> simply reads data from memory and so most applications do not care to check if there are any errors while fetching.   With <strong>mysql_unbuffered_query </strong> data comes in portions so you can well get an error while fetching rows.  If you do not check for error  it can look as you've done with result set while you only processed a portion of it, which can cause rather hard to catch errors. </li>
<li> <strong>Connection can timeout</strong> If you do not fetch data for long enough MySQL Server may think client is dead and close connection.  This well may happen if you need long processing for each row or have long periodic data flushes, ie with multiple value INSERTs etc.   This can be fixed by increasing  <strong>net_write_timeout</strong> variable on the server so it gives you more time </li>
</ol>
<p>But is this the only way  ? </p>
<p>Of course not.   First you should consider if you need to do processing in PHP at all.  Many summary tables can be built by INSERT ... SELECT,  or some others purely SQL commands and it can be much more efficient.   Another alternative is of course to use MySQL Stored Procedures which can be fit to do this simple job. </p>
<p>The downside of using these techniques if of course you've got to have summary tables and original tables on the same server which can limit your scalability. Using FEDERATED Tables can work for some cases in others script can be more efficient especially when multiple servers are involved and you want to do some parallel processing. </p>
<p>It is also good question if you need to query  all result at once. It is rather efficient  bur can cause problems with table locks and other issues plus if script aborts it may be hard to restart.    So it may be better structuring your queries to process data by certain objects (ie City by one City at the time)   or do INSERT ... SELECT to the temporary table with auto_increment column and fetch data from this table using auto increment column ranges instead.   I would especially recommend this last way for very long processes, ie if you need to check data against web services and so on - in this case the overhead of creating yet another temporary table is not so large. </p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/#comments">6 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/&amp;title=PHP  Large result sets and summary tables." title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/&amp;title=PHP  Large result sets and summary tables." title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/&amp;title=PHP  Large result sets and summary tables." title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/&amp;T=PHP  Large result sets and summary tables." title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/&amp;title=PHP  Large result sets and summary tables." title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2007/07/06/php-large-result-sets-and-summary-tables/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Integers in PHP, running with scissors, and portability</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/</link>
		<comments>http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/#comments</comments>
		<pubDate>Tue, 27 Mar 2007 20:53:22 +0000</pubDate>
		<dc:creator>shodan</dc:creator>
				<category><![CDATA[bugs]]></category>
		<category><![CDATA[lamp]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/</guid>
		<description><![CDATA[Until recently I thought that currently popular scripting languages, which mostly evolved over last 10 years or something, must allow for easier portability across different platforms compared to ye good olde C/C++.
After all, their development started a few decades after C, so its notorious caveats are all well-known and should be easy to avoid when [...]]]></description>
			<content:encoded><![CDATA[<p>Until recently I thought that currently popular scripting languages, which mostly evolved over last 10 years or something, <b>must</b> allow for easier portability across different platforms compared to ye good olde C/C++.</p>
<p>After all, their development started a few decades after C, so its notorious caveats are all well-known and should be easy to avoid when designing a new language, right?</p>
<p>However, PHP just brought me a new definition of "portable" - and that was when working with... integers.</p>
<p>PHP is not able to handle unsigned integers, and converts values over 2^31 to signed. So if your IDs go slightly over 2 billion, and PHP decides to treat them as integers, you're in trouble.</p>
<p>Oh wait, no - that's on 32-bit platforms only! PHP int size is platform-dependent, and it seems to be 8 bytes on our 64-bit boxes. Yes, the very same ones where C/C++ int is 4 bytes, you know.</p>
<p>That was the easy part. It was mostly documented.</p>
<p>Now, there's a function called unpack() which essentially allows to convert different types of data from binary strings to PHP variables. What if you try to unpack unsigned 32-bit big endian integer (format code "N")? Let's check the doc:</p>
<blockquote><p><a href="http://www.php.net/manual/en/language.types.integer.php">If you specify a number beyond the bounds of the integer type, it will be interpreted as a float instead.</a></p></blockquote>
<p>Having read the doc I personally blatantly relied upon it and expected that large unsigned 32bit numbers would be converted to float, or string, or something, but handled properly. However, a couple or so weeks ago the following notice suddenly appeared:</p>
<blockquote><p><a href="http://php.net/unpack">"Note that PHP internally stores integral values as signed. If you unpack a large unsigned long and it is of the same size as PHP internally stored values the result will be a negative number even though unsigned unpacking was specified."</a></p></blockquote>
<p>How sweet. No, it just could not behave like <b>documented</b> and convert 32-bit unsigned value to float on x32 or keep it integer on x64 - you <b>now</b> suddenly have to care about value <b>size</b> yourself. Ah, and by the way, there's no official way to know what's int size.</p>
<p>To make things even better, 5.2.1 introduced a nice bug in unpack(), which f..ed unpacking less-than-16-bit values on x64. (I assume you understand that "f..ed" means "fixed"). It took some time and <a href="http://bugs.php.net/bug.php?id=40543">several tries</a> to convince PHP team that x64 has enough bits to hold 16-bit unpacked value, but thankfully its now <a href="http://bugs.php.net/bug.php?id=40749">acknowledged and assigned</a>.</p>
<p>To summarize, if you need to unpack an unsigned 32bit int from binary stream, you have to:</p>
<ul>
<li>convert it to float or string manually,
<li>do that depending on int size on current platform,
<li>which can not be done using anything documented,
<li>and specifically avoid PHP 5.2.1 on x64.
</ul>
<p>Most people could probably learn all that, and then use sprintf("%u",$id), work with string IDs everywhere, avoid 5.2.1 and be happy.</p>
<p>Unfortunately, my final goal was to have support for 64-bit document IDs...</p>
<p>Let's do a small time travel. Integer types in C/C++ have always been a pain, but back in 1999 ISO commitee ratified ISO/IEC 9899:1999 standard, also known as ISO C99, which guarantees that "long long int" integer type must be at least 64 bits in size. By now, most compilers support that part perfectly.</p>
<p>However, designers of PHP 5 (released in 2004) type system were either not aware of this change, or decided to not rely on the standard which has been out for "only" 5 years by then, or just thought that 31 (no typo) bits and 640K should be enough for everybody.</p>
<p>Long story short, it's 2007 now but there's no native 64-bit integer type in PHP. Let me remind that built-in "int" <b>might</b> be 64-bit, but then again it might be <b>not</b>, and there's no official way to tell.</p>
<p>This time, there's a number of routes one could take - either use ints (and pray that the app is never run on x32, <b>and</b> that "platform dependent" size does not change to 4 next version); or use GMP or bcmath extensions if they are available.</p>
<p>Fine, so 99.999% of the world would hit that, compile in bcmath, and be happy again.</p>
<p>Unfortunately, I needed to develop a library which could be deployed in <b>any</b> environment - and still work, and produce reasonable results. The worst case is x32, and neither GMP nor bcmath available.</p>
<p>And this is how the following code was born.</p>
<div class="igBar"><span id="lphp-15"><a href="#" onclick="javascript:showPlainTxt('php-15'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-15">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">/// portably build 64bit id from 32bit hi and lo parts</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">function</span> _Make64 <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$hi</span>, <span style="color:#0000FF;">$lo</span> <span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// on x64, we can just use int</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>int<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#CC66CC;color:#800000;">4294967296</span><span style="color:#006600; font-weight:bold;">&#41;</span>!=<span style="color:#CC66CC;color:#800000;">0</span> <span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>int<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#0000FF;">$hi</span><span style="color:#006600; font-weight:bold;">&#41;</span>&lt;&lt;<span style="color:#CC66CC;color:#800000;">32</span><span style="color:#006600; font-weight:bold;">&#41;</span> + <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>int<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#0000FF;">$lo</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// workaround signed/unsigned braindamage on x32</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$hi</span> = <a href="http://www.php.net/sprintf"><span style="color:#000066;">sprintf</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"%u"</span>, <span style="color:#0000FF;">$hi</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$lo</span> = <a href="http://www.php.net/sprintf"><span style="color:#000066;">sprintf</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"%u"</span>, <span style="color:#0000FF;">$lo</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// use GMP or bcmath if possible</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <a href="http://www.php.net/function_exists"><span style="color:#000066;">function_exists</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"gmp_mul"</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> gmp_strval <span style="color:#006600; font-weight:bold;">&#40;</span> gmp_add <span style="color:#006600; font-weight:bold;">&#40;</span> gmp_mul <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$hi</span>, <span style="color:#FF0000;">"4294967296"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#0000FF;">$lo</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <a href="http://www.php.net/function_exists"><span style="color:#000066;">function_exists</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"bcmul"</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <a href="http://www.php.net/bcadd"><span style="color:#000066;">bcadd</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <a href="http://www.php.net/bcmul"><span style="color:#000066;">bcmul</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$hi</span>, <span style="color:#FF0000;">"4294967296"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#0000FF;">$lo</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// compute everything manually</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$a</span> = <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$hi</span>, <span style="color:#CC66CC;color:#800000;">0</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$b</span> = <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$hi</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$ac</span> = <span style="color:#0000FF;">$a</span>*<span style="color:#CC66CC;color:#800000;">42949</span>; <span style="color:#FF9933; font-style:italic;">// hope that float precision is enough</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$bd</span> = <span style="color:#0000FF;">$b</span>*<span style="color:#CC66CC;color:#800000;">67296</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$adbc</span> = <span style="color:#0000FF;">$a</span>*<span style="color:#CC66CC;color:#800000;">67296</span>+<span style="color:#0000FF;">$b</span>*<span style="color:#CC66CC;color:#800000;">42949</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$r4</span> = <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$bd</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span> +&nbsp; + <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$lo</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$r3</span> = <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$bd</span>, <span style="color:#CC66CC;color:#800000;">0</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span> + <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$adbc</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span> + <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$lo</span>, <span style="color:#CC66CC;color:#800000;">0</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$r2</span> = <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$adbc</span>, <span style="color:#CC66CC;color:#800000;">0</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span> + <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$ac</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$r1</span> = <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$ac</span>, <span style="color:#CC66CC;color:#800000;">0</span>, -<span style="color:#CC66CC;color:#800000;">5</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$r4</span>&gt;<span style="color:#CC66CC;color:#800000;">100000</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#0000FF;">$r4</span>-=<span style="color:#CC66CC;color:#800000;">100000</span>; <span style="color:#0000FF;">$r3</span>++; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$r3</span>&gt;<span style="color:#CC66CC;color:#800000;">100000</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#0000FF;">$r3</span>-=<span style="color:#CC66CC;color:#800000;">100000</span>; <span style="color:#0000FF;">$r2</span>++; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$r2</span>&gt;<span style="color:#CC66CC;color:#800000;">100000</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#0000FF;">$r2</span>-=<span style="color:#CC66CC;color:#800000;">100000</span>; <span style="color:#0000FF;">$r1</span>++; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$r</span> = <a href="http://www.php.net/sprintf"><span style="color:#000066;">sprintf</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"%d%05d%05d%05d"</span>, <span style="color:#0000FF;">$r1</span>, <span style="color:#0000FF;">$r2</span>, <span style="color:#0000FF;">$r3</span>, <span style="color:#0000FF;">$r4</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$l</span> = <a href="http://www.php.net/strlen"><span style="color:#000066;">strlen</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$r</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$i</span> = <span style="color:#CC66CC;color:#800000;">0</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$r</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$i</span><span style="color:#006600; font-weight:bold;">&#93;</span>==<span style="color:#FF0000;">"0"</span> &amp;&amp; <span style="color:#0000FF;">$i</span>&lt;<span style="color:#0000FF;">$l</span>-<span style="color:#CC66CC;color:#800000;">1</span> <span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$i</span>++;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#616100;">return</span> <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$r</span>, <span style="color:#0000FF;">$i</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/list"><span style="color:#000066;">list</span></a><span style="color:#006600; font-weight:bold;">&#40;</span>,<span style="color:#0000FF;">$a</span><span style="color:#006600; font-weight:bold;">&#41;</span> = <a href="http://www.php.net/unpack"><span style="color:#000066;">unpack</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"N"</span>, <span style="color:#FF0000;">"<span style="color:#000099; font-weight:bold;">\x</span>ff<span style="color:#000099; font-weight:bold;">\x</span>ff<span style="color:#000099; font-weight:bold;">\x</span>ff<span style="color:#000099; font-weight:bold;">\x</span>ff"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/list"><span style="color:#000066;">list</span></a><span style="color:#006600; font-weight:bold;">&#40;</span>,<span style="color:#0000FF;">$b</span><span style="color:#006600; font-weight:bold;">&#41;</span> = <a href="http://www.php.net/unpack"><span style="color:#000066;">unpack</span></a> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"N"</span>, <span style="color:#FF0000;">"<span style="color:#000099; font-weight:bold;">\x</span>ff<span style="color:#000099; font-weight:bold;">\x</span>ff<span style="color:#000099; font-weight:bold;">\x</span>ff<span style="color:#000099; font-weight:bold;">\x</span>ff"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$q</span> = _Make64<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$a</span>,<span style="color:#0000FF;">$b</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/var_dump"><span style="color:#000066;">var_dump</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$q</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>For reference, this is what would the equivalent C/C++ snippet look like:</p>
<div class="igBar"><span id="lcode-16"><a href="#" onclick="javascript:showPlainTxt('code-16'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-16">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">typedef unsigned long long myuint64; <span style="color:#FF9933; font-style:italic;">// just for brevity</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">unsigned int a = 0xffffffffULL;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">unsigned int b = 0xffffffffULL;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">myuint64 c = <span style="color:#006600; font-weight:bold;">&#40;</span>myuint64<span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#41;</span>&lt;&lt;<span style="color:#800000;color:#800000;">32</span><span style="color:#006600; font-weight:bold;">&#41;</span> + myuint64<span style="color:#006600; font-weight:bold;">&#40;</span>b<span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">printf <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0000;">"%llu"</span>, c <span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Portability in year 2007.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by shodan |
      <a href="http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/#comments">17 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/&amp;title=Integers in PHP, running with scissors, and portability" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/&amp;title=Integers in PHP, running with scissors, and portability" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/&amp;title=Integers in PHP, running with scissors, and portability" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/&amp;T=Integers in PHP, running with scissors, and portability" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/&amp;title=Integers in PHP, running with scissors, and portability" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>PHP Sessions &#8211; Files vs Database Based</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/</link>
		<comments>http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/#comments</comments>
		<pubDate>Tue, 27 Mar 2007 16:26:42 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[lamp]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/</guid>
		<description><![CDATA[One may think changing PHP session handler from file based to database driven is fully transparent.  In many cases it is, sometimes however it may cause some unexpected problems as happened to one of our customers.
If you use file based sessions PHP will lock  session file for whole script execution duration, which means [...]]]></description>
			<content:encoded><![CDATA[<p>One may think changing PHP session handler from file based to database driven is fully transparent.  In many cases it is, sometimes however it may cause some unexpected problems as happened to one of our customers.</p>
<p>If you use file based sessions PHP will lock  session file for whole script execution duration, which means all requests from the same sessions will be serialized on PHP level, which means they also will be serialized for single user on database level.   If you change to store PHP sessions in MySQL instead this effect  may be no more true and you may have number of requests executing for the same session at the same time.  First of course means you may have your session data damaged  because you will have lost session variables update from one of the script, in addition however you may run into database related issues  of modifying user profile or other user/session related data in parallel, if you do not use transactions or lock tables. </p>
<p>So how you can get back your old file based session behavior with MySQL Sessions ?</p>
<p>If you have dedicated connection to session database and use Innodb tables for your session storage you can  start transaction on the session start and use SELECT ... FOR UPDATE  to lock the session row in the session table for whole request length.  On the end of the session the same row is updated and transaction is committed. </p>
<p>If you share session connection with other modules or do not use transactional tables for session you can use GET_LOCK to get same behavior.   In the start of the session you can do SELECT  GET_LOCK('<session_id>',10)  and in in the end of the request<br />
SELECT RELEASE_LOCK('<session_id>') where session_id is current session identifier.   Note - setting this external lock on session name should be done before session data is read from database for things to work properly.</p>
<p>This approach assumes you do not use GET_LOCK in other places in your application as as soon as it is called second time previous lock is automatically released. The good thing about it however - you can use it as an extra to your current MySQL Sessions system without need to change how it works internally.   If you do not use persistent connections you even do not have to release lock - as soon as connection is closed the lock is automatically released. </p>
<p>The value 10 in GET_LOCK is timeout in seconds - if lock can't be granted for this amount of time it will return "0" indicating lock was not granted in this case you can select to continue without session or may do something else, like logging error as this generally should not happen in well tuned applications. </p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/#comments">26 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/&amp;title=PHP Sessions &#8211; Files vs Database Based" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/&amp;title=PHP Sessions &#8211; Files vs Database Based" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/&amp;title=PHP Sessions &#8211; Files vs Database Based" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/&amp;T=PHP Sessions &#8211; Files vs Database Based" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/&amp;title=PHP Sessions &#8211; Files vs Database Based" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Content delivery system design mistakes</title>
		<link>http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/</link>
		<comments>http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/#comments</comments>
		<pubDate>Sun, 11 Feb 2007 11:37:42 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[lamp]]></category>
		<category><![CDATA[production]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/</guid>
		<description><![CDATA[This week I helped dealing with performance problems (part MySQL related and part related to LAMP in general) of system which does quite a bit of content delivery, serving file downloads and images - something a lot of web sites need to do these days.  There were quite a bit of mistakes in design [...]]]></description>
			<content:encoded><![CDATA[<p>This week I helped dealing with performance problems (part MySQL related and part related to LAMP in general) of system which does quite a bit of content delivery, serving file downloads and images - something a lot of web sites need to do these days.  There were quite a bit of mistakes in design for this one which I though worth to note, adding some issues seen in other systems.   </p>
<p>Note this list applies to static content distribution, dynamic content has some of its own issues which need different treatment.</p>
<p><strong>DNS TTL Settings </strong>  The system was using DNS based load balancing, using something like img23.domain.com to serve some of the images.   I'm not big fan of purely DNS based load balancing and HA but it works if configured well. In this case however the problem was zero TTL set in DNS configuration.  This obviously adds latency especially for "aggregate" pages which may require images to be pulled from 10 different image servers.   </p>
<p><strong>Keep Alive </strong>   In my <a href="http://www.mysqlperformanceblog.com/2007/02/05/why-do-you-need-many-apache-children/">previous post</a>  I wrote you often do not need keep alive for dynamic pages (there are also exceptions) but you really should have Keep Alive enabled while serving images. It especially hurts not to have one if 30 thumbnails are loaded  per page if you do not have one.  </p>
<p><strong>Use Proper Web Server </strong> This one is pretty interesting. Many learned apache is not good for serving static content especially with many thousands of keep-alive connections. <a href="http://www.lighttpd.net">Lighttpd</a> is often named as faster alternative.  It is surely true if you server static content from memory or serving large files (in which case read-ahead helps) but if you're serving many millions of thumbnails it may not work well.  Lighttpd 1.4 is single threaded and that single threads is used to handle both network and IO which is not going to scale especially if you have storage build from large number of hard drives.  This problem is fixed in Lighttpd 1.5 which is however still in pre-release (though we have it running in production).  There are other solutions such as <a href="http://nginx.net/">nginx</a> which does not seems to have this problem.   My point with this item is not advice you which exactly web server to use but to point out serving dynamic content, serving in-memory static content and serving static content from the disk are different tasks and should not be mixed.  </p>
<p><strong>Use  noatime mount option</strong>  Serving images you rarely need last access time tracked for them, especially as this tracking can be quite expensive if there are a lot of different files accessed concurrently. It is especially worth to note updating access time needs io even in case content is in OS cache.   Simple solution is use <strong>noatime </strong> mount option for your static content partition.  Some web servers also support for O_NOATIME file open flag on newer Linux versions, which also can be used. </p>
<p><strong>Using PHP to serve files  </strong> This usually comes in play if security control for files or traffic limit per user needs to be enforced.   Serving file by simply reading from PHP or any other heavy programming language and sending it back is worse thing you can do.  The optimal solution would be to using some server modules for access control or hacking one if you need some special functionality, few people however have skills to do this kind of job.  The other solution is to use X-send-file  or similar custom headers which make PHP script just to check restrictions and have web server to send the file.    This technique actually was used in the project we're speaking about with exception of resuming file downloads.   In lighttpd 1.4 you could not tell server to send only part of the file so it had to be implemented in php.  However even small portion of such downloads caused a lot of trouble especially as lighttpd tries to buffer all content it gets from PHP script which means many megabytes for large files.  Partial file sending happily was added in lighttpd 1.5 which was one of the reason to move to it quickly.</p>
<p><strong>Thumbnail size </strong>  In many cases you need multiple sizes of thumbnails, such as very small size to show in list mode, standard size to show in preview mode and may be something else.   It looks very attractive to keep only one thumbnail and simply set browser image sizes if you need to stick it to smaller space.  It is not so good in practice however. First browsers may not resize image with optimal quality and it may just look ugly compared to properly created thumbnails.  It also makes things a lot slower. I for example seen 8K thumbnail in the case when smallest one should have been less than 1KB in size.  With 30 images on the page it is 30KB worth of download vs 240KB which makes quite a bit of difference especially on slower connection speeds.  </p>
<p><strong>Forgetting to set expire </strong> Static content rarely changes, in many implementations it may never change as loading new version of the same object will result in different url. This means you really need to have expire headers for them set, otherwise you will be getting a lot of cache revalidation requests which still require stat() calls on web server side and which can be avoided.  How far in the future you want expire to be... it depends on the application of course. It can range for few hours for objects changes to which you want to be quickly visible to infinity for objects which only change with their urls. </p>
<p><strong>Server side caching </strong>  The benefit of server side caching is not so obvious for serving static content, or better say it depends on situation.  If you serve a lot of small files which can fit in squid (for example) in-memory cache it may work quite well and in fact will give better memory utilization as OS cache has single page granularity (meaning 100 bytes file will still take 4KB in cache).  For serving large set of files (which does not fit in memory) you can have performance to go down as request will be frequently made to the main server to get the file.  Also it frequently does not make sense to use disk cache for static content as getting it from the server may be close in speed.   It also of course depends on the server which you're using - apache in prefork mode (ie same server used for static and dynamic content) would likely to benefit a lot from one. </p>
<p><strong>Using different servers </strong> As I already mentioned serving different content requires different skills from web servers or different configuration, so it is good idea to use dedicated server name, such as static.domain.com for serving static content, so even if you do not need it now you have flexibility in the future.  Also even for same server it allows to configure different virtual host with different settings easily. </p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/#comments">7 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/&amp;title=Content delivery system design mistakes" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/&amp;title=Content delivery system design mistakes" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/&amp;title=Content delivery system design mistakes" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/&amp;T=Content delivery system design mistakes" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/&amp;title=Content delivery system design mistakes" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2007/02/11/content-delivery-system-design-mistakes/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Debugging sleeping connections with MySQL</title>
		<link>http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/</link>
		<comments>http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/#comments</comments>
		<pubDate>Thu, 08 Feb 2007 10:36:25 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[lamp]]></category>
		<category><![CDATA[production]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/</guid>
		<description><![CDATA[Have you ever seen connection in the SHOW PROCESSLIST output  which is in "Sleep" state for a long time  and you have no idea why this would happen ? 
I see if  frequently with web applications and it is often indication of trouble.  Not only it means you may run out [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever seen connection in the <strong>SHOW PROCESSLIST</strong> output  which is in "Sleep" state for a long time  and you have no idea why this would happen ? </p>
<p>I see if  frequently with web applications and it is often indication of trouble.  Not only it means you may run out of MySQL connections quicker than you expected but it also frequently indicates serious problems in the application.   If you do not use persistent connections and you have  connection in Sleep stage for 600 seconds what could it be ? It may mean some of your pages take that long to generate (or might be the code simply gets into the tight loop and page never gets generated) it also could mean some of external Web Services are slow or not available and you're not dealing with timeouts properly.   Or may be you have several connections to MySQL server and right now running query which takes that long ?  In any case it is something frequently worth looking at. </p>
<p>First task is to find to which process the connection belongs.   Using different user names for different application is a good practice however it will not tell you which of apache children is handling request in question.   If you just want to fix it, ie by restarting apache it is enough but if you want to figure our why it is happening you need more info. </p>
<p>You my notice in the "Host" filed of SHOW PROCESSLIST output not only host but also port is specified, showing you something like<br />
"192.168.1.70:58555"    This port can be used to  identify the process which owns connection in question:</p>
<p>[code]<br />
[root@w1 ~]# netstat -ntp | grep :45384<br />
tcp        0      0 192.168.1.70:45384          192.168.1.82:3306           ESTABLISHED 28540/php-cgi<br />
[\code]</p>
<p>As you can see in this case we can find php-cgi  is holding connection in question (this is <a href="http://www.lighttpd.net">lighttpd</a> based system with fastcgi)</p>
<p>Now you know the process and you can use your favorite tools to check what that process is doing.   </p>
<p>[code]<br />
[root@w1 ~]# netstat -ntp | grep 28540<br />
tcp        0      0 192.168.1.70:58555          192.168.1.90:11211          ESTABLISHED 28540/php-cgi<br />
tcp        0      0 192.168.1.70:52711          192.168.1.88:8080           ESTABLISHED 28540/php-cgi<br />
tcp        0      0 192.168.1.70:45384          192.168.1.82:3306           ESTABLISHED 28540/php-cgi<br />
tcp        0      0 192.168.1.70:45399          192.168.1.82:3306           ESTABLISHED 28540/php-cgi<br />
tcp        0      0 192.168.1.70:45407          192.168.1.82:3306           ESTABLISHED 28540/php-cgi<br />
tcp        0      0 192.168.1.70:45408          192.168.1.82:3306           ESTABLISHED 28540/php-cgi<br />
tcp        0      0 192.168.1.70:35556          192.168.1.92:11211          ESTABLISHED 28540/php-cgi<br />
[\code]</p>
<p>Using same <strong>netstat</strong> command and filtering on the PID we can find which connections does this process have.  Here you can see it has couple of memcached connections. Few MySQL connections (to the same host, which if usually bad idea) and connection to some external web server. </p>
<p>You can use <strong>strace -p
<pid></strong>   to see what host is doing, it often gives a clue. In this case I for example found the process is stuck in pool() system call reading from network.  Using netstat can give you an idea what it can be but if you do not like guessing you can use  <strong>gdb -p
<pid></strong>. It will not print you exact line of code in PHP which is running but can give you some good ideas - for example in this case I could find stack trace originated from php stream functions not from libmysql or memcache.so, which means it is not MySQL or memcache connections leaving last candidate as the only choice.  I also could see some of the variables in GDB "bt"  command output which also hinted what could be the problem.</p>
<p>By the way does anyone know any debugger which can connect to PHP process or apache with mod_php and provide backtrace in PHP terms not the one for zend engine ? That would be pretty cool. </p>
<p>Yet another great tool which you can use is  server-status if you're running apache.  This way you will see the URL which that process is processing and so get few more hints on what may be happening or even get repeatable example in some cases.</p>
<p>The tools I mentioned regarding figuring our what is happening with the process are not only helpful to debug sleeping connections with MySQL but many other cases when you see  web application locking up or starting to runs in the tight loop consuming too much CPU time. </p>
<p>If you know any other tools which could be helpful in this regard would appreciate your comments. There might be some smarter tools out where for production tracing. </p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/#comments">19 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/&amp;title=Debugging sleeping connections with MySQL" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/&amp;title=Debugging sleeping connections with MySQL" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/&amp;title=Debugging sleeping connections with MySQL" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/&amp;T=Debugging sleeping connections with MySQL" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/&amp;title=Debugging sleeping connections with MySQL" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>
