<?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>Eric Bergen &#187; General</title>
	<atom:link href="http://ebergen.net/wordpress/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://ebergen.net/wordpress</link>
	<description>You will probably want some waders, a pickaxe, and one of those hats with a light on it before you go in here.</description>
	<lastBuildDate>Thu, 29 Dec 2011 18:25:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Update on porting table_statistics to MariaDB</title>
		<link>http://ebergen.net/wordpress/2011/04/24/update-on-porting-table_statistics-to-mariadb-2/</link>
		<comments>http://ebergen.net/wordpress/2011/04/24/update-on-porting-table_statistics-to-mariadb-2/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 05:59:00 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[MariaDB]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/?p=475</guid>
		<description><![CDATA[Over the past few weeks I&#8217;ve been working on porting the per table and per session row stats from the tivo patch into mariadb. This is the show table_statistics functionality. I&#8217;ve been pushing the code to a branch on lanchpad as I get features working. Up to revision 2953 the row stats are working but [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past few weeks I&#8217;ve been working on porting the per table and per session row stats from the <a href="http://ebergen.net/wordpress/2010/09/28/cool-stuff-from-tivos-mysql-patch/">tivo patch</a> into mariadb. This is the show table_statistics functionality.  I&#8217;ve been pushing the code to <a href="https://code.launchpad.net/~provenscaling-eric/maria/tivo">a branch</a> on lanchpad as I get features working. Up to revision 2953 the row stats are working but the index stats aren&#8217;t. I think I have a reasonable implementation of the row stats code given my level of C++ skill. I&#8217;m changing the syntax a bit from how it worked in the tivo patch to make it be more compatible with how the original row stats code worked that was ported into mariadb. </p>
<p>In MariaDB 5.2 there are show table_statistics show index_statistics, and show user_statistics functions that return global stats collected by the server when the userstats variable is enabled. There are also associated information schema tables that feed these commands. So far I&#8217;ve changed the syntax of the show command to be </p>
<blockquote><p>SHOW [ QUERY | SESSION | GLOBAL ] TABLE_STATISTICS</p></blockquote>
<p>Where the default show table_statistics returns the global stats. This is different from the tivo patch against 5.0.72 which changed the default to be the last query. The new syntax keeps things backwards compatible with the original show command. The query keyword will return the previous query_statistics_history_size queries of statistics. This is a bit different from the 5.0 version which only tracked one query. </p>
<p>For example if I set query_statistics_history_size=5 then mariadb will track the row stats from the previous 5 queries:</p>
<blockquote><p>mysql> set query_statistics_history_size=5;<br />
Query OK, 0 rows affected (0.00 sec)</p>
<p>mysql> show tables;<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
| Tables_in_test |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
| t              |<br />
| t2             |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
2 rows in set (0.00 sec)</p>
<p>mysql> select * from t;<br />
+&#8212;+<br />
| t |<br />
+&#8212;+<br />
| 1 |<br />
| 2 |<br />
| 3 |<br />
| 4 |<br />
| 5 |<br />
+&#8212;+<br />
5 rows in set (0.00 sec)</p>
<p>mysql> select * from t2;<br />
+&#8212;-+<br />
| t2 |<br />
+&#8212;-+<br />
|  1 |<br />
|  2 |<br />
|  3 |<br />
+&#8212;-+<br />
3 rows in set (0.00 sec)</p>
<p>mysql> show query table_statistics;<br />
+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
| Query_id | Table_schema | Table_name | Rows_read | Rows_changed | Rows_changed_x_#indexes |<br />
+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
|       81 | test         | t          |         5 |            0 |                       0 |<br />
|       82 | test         | t2         |         3 |            0 |                       0 |<br />
+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
2 rows in set (0.00 sec)</p>
<p>mysql> select count(*) from t,t2;<br />
+&#8212;&#8212;&#8212;-+<br />
| count(*) |<br />
+&#8212;&#8212;&#8212;-+<br />
|       15 |<br />
+&#8212;&#8212;&#8212;-+<br />
1 row in set (0.00 sec)</p>
<p>mysql> show query table_statistics;<br />
+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
| Query_id | Table_schema | Table_name | Rows_read | Rows_changed | Rows_changed_x_#indexes |<br />
+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
|       81 | test         | t          |         5 |            0 |                       0 |<br />
|       82 | test         | t2         |         3 |            0 |                       0 |<br />
|       84 | test         | t          |         5 |            0 |                       0 |<br />
|       84 | test         | t2         |         3 |            0 |                       0 |<br />
+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
4 rows in set (0.00 sec)</p></blockquote>
<p>Note that show query table_statistics shows the stats only for the current connection. There isn&#8217;t a way to get lists from other threads. My next task is to add a separate table with the query_id and query text similar to show profiles that can be used to correlate a query back to the different statistics kept for it. After that I plan on adding index statistics.</p>
<p>The older version of this in the tivo patch has been extremely useful for optimizing queries. I hope I can make this even better and get it into mariadb for other people to use. If you have any suggestions for how I should change this please post in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2011/04/24/update-on-porting-table_statistics-to-mariadb-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cool stuff from TiVo&#8217;s MySQL patch</title>
		<link>http://ebergen.net/wordpress/2010/09/28/cool-stuff-from-tivos-mysql-patch/</link>
		<comments>http://ebergen.net/wordpress/2010/09/28/cool-stuff-from-tivos-mysql-patch/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 17:00:53 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/?p=411</guid>
		<description><![CDATA[While not as well known as the Google or Facebook patches the TiVo mysql patch includes some changes that make monitoring and query optimization a bit easier than mainline MySQL. The modified tarball, available at http://www.tivo.com/mysql/ contains a modified mysqld_safe, mysqldump, and improvements to the row statistics show commands that came from google. mysqld_safe modifications [...]]]></description>
			<content:encoded><![CDATA[<p>While not as well known as the Google or Facebook patches the TiVo mysql patch includes some changes that make monitoring and query optimization a bit easier than mainline MySQL. The modified tarball, available at http://www.tivo.com/mysql/ contains a modified mysqld_safe, mysqldump, and improvements to the row statistics show commands that came from google. </p>
<p><strong>mysqld_safe modifications</strong></p>
<p><strong>&#8211;fallback-ledir</strong><br />
The &#8211;ledir option tells mysqld_safe which directory contains the mysqld file that it should use. TiVo has added the &#8211;fallback-ledir option which will switch the ledir should mysqld crash. This makes it possible to run a new mysqld binary then fallback to the stock one should the new one crash. This feature has never been called to duty in production but it makes me sleep better. </p>
<p><strong>&#8211;crash-script </strong><br />
This is a new option to mysqld_safe which will execute a script when it detects mysqld has crashed. This can be useful for gathering diagnostic info, sending monitoring alerts or even triggering a failover. Remember if you choose to use this option to trigger a failover make sure your failover mechanism has flap prevention so the master won&#8217;t ping/pong back and forth between servers. </p>
<p><strong>mysqldump modifications</strong></p>
<p><strong>&#8211;slave-data</strong><br />
I think this option has been implemented by several people. We have also added it because it makes life easier for making backups. What this does is mark the replication position of the slave thread in the mysqldump output. It&#8217;s also useful for creating a dump file from a slave and using it to restore a peer slave. </p>
<p><strong>&#8211;log-pos-comment</strong><br />
This makes dump files a little bit friendlier for restoring backups on one of an HA pair of machines. It writes out a pair of comments with replication positions from both the slave thread and the master position in a human readable format. This is handy for debugging restore scripts as well as those rare situations when a backup needs to be restored by hand. </p>
<p><strong>&#8211;no-bin-log</strong><br />
This tells mysqldump to write a SET SQL_LOG_BIN=0; to the top of the dump file in the same way other variables are set. This makes dump files import only on the machine and not be written to the replication stream. It makes dump files a bit safer for importing on an HA pair. TiVo has multiple tools that work with sqldump files so this was a good mechanism to make the dump files replication safe. </p>
<p>The rest of the modifications are in mysqld itself. TiVo makes extensive use of the row stats options originally created at Google. The command syntax has been modified from Google&#8217;s original version to make it easier for developers to use the commands to debug queries as well as allowing the application servers themselves to access the data per session or per query.</p>
<p>TiVo has complicated MySQL queries, really complicated. Sometimes it&#8217;s difficult to figure out which part of the query is doing the most work or what changed the performance between two different versions of a query. One way to help solve that problem is to keep track of the rows being accessed in a query both for that query and for the session. </p>
<p><strong>This description applies for both SHOW TABLE_STATISTICS and SHOW INDEX_STATISTICS commands.</strong></p>
<p>Row stats in the TiVo patch are tracked at 3 different levels, per query, per session, and globally. The original Google patch only tracked row stats globally. Tracking them per session and per query doesn&#8217;t add much overhead and provides valuable information about query performance. It&#8217;s true that not every row access is the same but this has provided an easier measure for work done by a query than wall clock time or even rows examined from the slow query log. </p>
<p>After a query has executed the row statistics for that query can be accessed with:</p>
<pre>mysql> select * from t;
+------+
| t    |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

mysql> show table_statistics;
+--------+-----------+--------------+-------------------------+
| Table  | Rows_read | Rows_changed | Rows_changed_x_#indexes |
+--------+-----------+--------------+-------------------------+
| test.t |         3 |            0 |                       0 |
+--------+-----------+--------------+-------------------------+
1 row in set (0.00 sec)</pre>
<p>If the query is executed again show table_statistics will still only return results for the previous query but show session table_statistics will return cumulative counts for the duration of the session. The rows changed in the session query is from the insert statement which I used to create the test table. </p>
<pre>mysql> select * from t;
+------+
| t    |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

mysql> show table_statistics;
+--------+-----------+--------------+-------------------------+
| Table  | Rows_read | Rows_changed | Rows_changed_x_#indexes |
+--------+-----------+--------------+-------------------------+
| test.t |         3 |            0 |                       0 |
+--------+-----------+--------------+-------------------------+
1 row in set (0.00 sec)

mysql> show session table_statistics;
+--------+-----------+--------------+-------------------------+
| Table  | Rows_read | Rows_changed | Rows_changed_x_#indexes |
+--------+-----------+--------------+-------------------------+
| test.t |         6 |            3 |                       3 |
+--------+-----------+--------------+-------------------------+
1 row in set (0.00 sec)
</pre>
<p>The final way to access the row statistics is the global count for the server. All of these commands also support using like syntax to narrow down the list of tables. In this case I&#8217;m showing the global stats which include the mysql tables. </p>
<pre>mysql> show global table_statistics like 'mysql%';
+----------------------+-----------+--------------+-------------------------+
| Table                | Rows_read | Rows_changed | Rows_changed_x_#indexes |
+----------------------+-----------+--------------+-------------------------+
| mysql.proc           |       293 |            4 |                       4 |
| mysql.user           |  10237928 |            2 |                       2 |
| mysql.help_category  |        36 |            0 |                       0 |
| mysql.help_topic     |       463 |            0 |                       0 |
| mysql.help_relation  |       733 |            0 |                       0 |
| mysql.help_keyword   |       381 |            0 |                       0 |
| mysql.db             |  10964886 |            0 |                       0 |
+----------------------+-----------+--------------+-------------------------+
8 rows in set (0.00 sec)
</pre>
<p>Since these statistics are readily available within MySQL the TiVo patch modifies the slow query log header to include table and index statistics. </p>
<pre># Time: 100725 14:39:33
# User@Host: tivo[tivo] @ localhost []
# Query_time: 3  Lock_time: 0  Rows_sent: 3  Rows_examined: 3
# Row_Stats: test.t:rows_read=3,rows_changed=0,rows_changed_x_indexes=0;
# Index_Stats:
select *, sleep(1) from t;</pre>
<p>The TiVo patch also includes changes to InnoDB from the Google patch and from Percona. </p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2010/09/28/cool-stuff-from-tivos-mysql-patch/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Sun&#8217;s official support for Drizzle means more than just code.</title>
		<link>http://ebergen.net/wordpress/2008/10/02/suns-official-support-for-drizzle-means-more-than-just-code/</link>
		<comments>http://ebergen.net/wordpress/2008/10/02/suns-official-support-for-drizzle-means-more-than-just-code/#comments</comments>
		<pubDate>Fri, 03 Oct 2008 04:07:55 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/?p=192</guid>
		<description><![CDATA[As Jeremy wrote a few months ago one of the main issues with forking MySQL is the documentation is not open source. Today Jay Pipes announced that he is leaving the MySQL Community Team to be a staff engineer for Sun on the Drizzle project. Monty Taylor also released a similar announcement saying that he [...]]]></description>
			<content:encoded><![CDATA[<p>As Jeremy <a href="http://jcole.us/blog/archives/2008/07/23/on-mysql-forks-and-mysqls-non-open-source-documentation/">wrote</a> a few months ago one of the main issues with forking MySQL is the documentation is not open source. Today Jay Pipes <a href="http://jpipes.com/index.php?/archives/263-guid.html">announced</a> that he is leaving the MySQL Community Team to be a staff engineer for Sun on the Drizzle project. Monty Taylor also released a <a href="http://mysql-ha.com/2008/10/02/when-it-rains/">similar announcement</a> saying that he will also be working on Drizzle full time. </p>
<p>This means that Drizzle is no longer a side project hacked on by a few engineers outside of their work time, it&#8217;s an official project. With Sun employing Drizzle engineers and Sun owning the copyright to the MySQL documentation it&#8217;s now likely that Sun will create Drizzle docs from the existing MySQL docs to support their new product. The question now is how will the docs be licensed? Will Drizzle enjoy the fork protection that MySQL has for so many years by keeping it&#8217;s documentation hostage? Probably. If Sun creates docs based on the MySQL docs they will own the copyright and effectively own Drizzle.</p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2008/10/02/suns-official-support-for-drizzle-means-more-than-just-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac OS A2DP and FreePulse Logitech Headphones</title>
		<link>http://ebergen.net/wordpress/2008/09/08/mac-os-a2dp-and-freepulse-logitech-headphones/</link>
		<comments>http://ebergen.net/wordpress/2008/09/08/mac-os-a2dp-and-freepulse-logitech-headphones/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 06:12:14 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/?p=191</guid>
		<description><![CDATA[Apple is slowly fixing the many issues with it&#8217;s A2DP driver. In 10.4 the driver would kernel panic as often as it would work. In 10.5 it&#8217;s functional but only with a special trick to get it to change the audio channel correctly. Simply turning on the headphones and clicking &#8220;Use Headphones&#8221; on the dialog [...]]]></description>
			<content:encoded><![CDATA[<p>Apple is slowly fixing the many issues with it&#8217;s A2DP driver. In 10.4 the driver would kernel panic as often as it would work. In 10.5 it&#8217;s functional but only with a special trick to get it to change the audio channel correctly. Simply turning on the headphones and clicking &#8220;Use Headphones&#8221; on the dialog rarely works. </p>
<p>The trick is to run through this sequence twice. Turn on the headphones by holding the button on the right ear. After you hear the ping Mac OS will prompt you to use the headphones. Choose the option to use the headphones and the bluetooth icon will switch to connected. Now turn on the headphones again and when you hear them ping the bluetooth icon should switch back to disconnected. Under the bluetooth menu choose &#8220;Use Headphones&#8221; under the FreePulse device. The icon will stay disconnected but when you play audio it will switch to connect and start functioning. </p>
<p>I couldn&#8217;t find a place on apple&#8217;s site to report the bug with repeatable test case. If any of you know how to report bugs in Mac OS please tell me and I&#8217;ll file it so hopefully this behavior is fixed in future releases. </p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2008/09/08/mac-os-a2dp-and-freepulse-logitech-headphones/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Solving the final issue with electric cars.</title>
		<link>http://ebergen.net/wordpress/2008/08/16/solving-the-final-issue-with-electric-cars/</link>
		<comments>http://ebergen.net/wordpress/2008/08/16/solving-the-final-issue-with-electric-cars/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 02:17:39 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/?p=189</guid>
		<description><![CDATA[For the past few years hyrbids have been all the rage. Now electric cars are coming on to the scene. I realized a while ago that neither of these vehicles is good for the great american tradition of the road trip. Before gas prices started to increase it was fairly common to pack up the [...]]]></description>
			<content:encoded><![CDATA[<p>For the past few years hyrbids have been all the rage. Now electric cars are coming on to the scene. I realized a while ago that neither of these vehicles is good for the great american tradition of the road trip. Before gas prices started to increase it was fairly common to pack up the family car and head across the country. This is still my preferred way to travel. I hate the uncertainty and the TSA interaction of flying. Driving is nice and relaxing once you get out of traffic. </p>
<p>Hybrids are fine for city driving but they offer no improvement over your typical four-banger once you get out on to the highway or back in the woods. Let&#8217;s face it, most hybrids have no business off pavement. In a few years I&#8217;m sure decent hybrid trucks will become available. I&#8217;m not holding my breath. </p>
<p>The other alternative is electric cars. They&#8217;re great for the daily commute. You drive to work and back then plug them in when you get home a night. Electric cars are great because we have so many different clean options for generating power. The typical range is 200 miles so they have plenty of juice to go to work and grab groceries on the way home. If you need to drive outside that range you&#8217;re effectively screwed. After the juice runs out the car has to be plugged in for hours before you can make go another 200 miles.</p>
<p>In order to get people to switch over to all electric cars we need to have the range of a gas fueled engine plus the ease of refueling. Since we can&#8217;t recharge batteries as fast as we can fill a tank with gas the only other option is to change the batteries out. I think we need to standardize on battery size and have them removed from the bottom of the car. Then instead of gas stations we can have automated robots that will drop all the batteries out of the bottom of a car and place charged batteries in. Think of it like driving through an automated car wash like device but instead of cleaning your car it drops the batteries out of the bottom and puts new ones in. This eliminates two problems with electric cars. First it means we can recharge electric cars as fast as or faster than gas cars and as long as there are battery change out stations we can continue to go on road trips. It also means that there is no longer an issue with the huge cost of replacing batteries after a few years. Part of the recharge cost will also be maintenance on the batteries. It&#8217;s like the propane exchange at your local grocery store. </p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2008/08/16/solving-the-final-issue-with-electric-cars/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ptrace on threads and linux signal handling issues</title>
		<link>http://ebergen.net/wordpress/2008/06/25/ptrace-on-threads-and-linux-signal-handling-issues/</link>
		<comments>http://ebergen.net/wordpress/2008/06/25/ptrace-on-threads-and-linux-signal-handling-issues/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 02:10:33 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/?p=182</guid>
		<description><![CDATA[At Proven Scaling it&#8217;s not always all about scaling databases. Sometimes we get to solve other problems not related to scaling at all. We have a client that has been using jmap (unsupported) to grab memory statistics from java. They found that after they ran jmap they were unable to shutdown the jvm without it [...]]]></description>
			<content:encoded><![CDATA[<p>At Proven Scaling it&#8217;s not always all about scaling databases. Sometimes we get to solve other problems not related to scaling at all. We have a client that has been using jmap (unsupported) to grab memory statistics from java. They found that after they ran jmap they were unable to shutdown the jvm without it hanging. </p>
<p>After working on the problem for a bit I found that after jmap ran ps showed the java process as stopped. This is strange since java was still able to process requests. In linux threads are treated as processes, they get a pid just like any other process. To be POSIX compliant linux has the notion of thread groups and a thread group leader so signals can be delivered to an entire thread group.</p>
<p>[Update: 2009-05-19 The version of jmap that ships with jdk-1.6 detaches correctly]</p>
<p>jmap gets memory statistics by using ptrace on the pid of the thread group leader. When ptracing a thread group leader only that thread is stopped and analyzed. Other threads are free to continue processing. Jmap is a bit buggy in that it attaches to a thread but never detaches. Linux has a safe guard that if the parent of a traced process quits then linux changes the traced processes&#8217; state from traced to stopped because traced processes can&#8217;t be killed. </p>
<p>When jmap quits the ps shows the process in state T which means stopped. What it doesn&#8217;t say is that only the thread group leader is stopped. To get around the limitations of ps and process states I went directly to proc to get the process state. The example below was done using mysqld instead of java. It shows the process state of all the threads, including the leader during a simulated jmap run. </p>
<p>In this example 20924 is the pid of mysqld. I substituted mysql for java in this example because I had it handy on my dev server. It reacts the same way java does. The bad_trace app simulates jmap by doing a ptrace attach and exiting before a detach. It sleeps for a big in the middle so I can get the process state of a normal traced process. Here is the source for bad_trace if you want to follow along at home.</p>
<p><tt><br />
#include &lt;unistd.h&gt;<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;sys/ptrace.h&gt;</p>
<p>int main(int argc, char **argv)<br />
{<br />
  pid_t pid = 0;</p>
<p>  if (argc < 2)<br />
  {<br />
    printf("First arg should be a pid\n");<br />
    return 1;<br />
  }</p>
<p>  printf("argc %d\n", argc);<br />
  pid = atoi(argv[1]);<br />
  printf("Attaching to pid (%d)\n", pid);<br />
  ptrace(PTRACE_ATTACH, pid, NULL, NULL);<br />
  printf("Sleeping for ten seconds\n");<br />
  sleep (10);</p>
<p>  return 0;<br />
}<br />
</tt></p>
<p>The bad_trace app does a ptrace attach and exits without detaching. </p>
<p>This is the normal state on an idle server all threads are sleeping. </p>
<p></tt><tt>ebergen@kamet:(/proc/20924/task) grep State */status<br />
20924/status:State:	S (sleeping)<br />
20926/status:State:	S (sleeping)<br />
20927/status:State:	S (sleeping)<br />
20928/status:State:	S (sleeping)<br />
20929/status:State:	S (sleeping)<br />
20931/status:State:	S (sleeping)<br />
20932/status:State:	S (sleeping)<br />
20933/status:State:	S (sleeping)<br />
20934/status:State:	S (sleeping)<br />
</tt></p>
<p>I execute bad_trace which puts the thread group leader into traced mode waiting for bad_trace to examine it. </p>
<p><tt><br />
ebergen@kamet:(/proc/20924/task) ~/bad_trace 20924<br />
Attaching to pid (20924)<br />
Sleeping for ten seconds<br />
[1]+  Stopped                 ~/bad_trace 20924<br />
</tt></p>
<p>I suspend bad_trace to grab the stats. You can see that the thread group leader has stopped in tracing mode waiting for bad_trace to examine it and tell it to continue. </p>
<p><tt><br />
ebergen@kamet:(/proc/20924/task) grep State */status<br />
20924/status:State:	T (tracing stop)<br />
20926/status:State:	S (sleeping)<br />
20927/status:State:	S (sleeping)<br />
20928/status:State:	S (sleeping)<br />
20929/status:State:	S (sleeping)<br />
20931/status:State:	S (sleeping)<br />
20932/status:State:	S (sleeping)<br />
20933/status:State:	S (sleeping)<br />
20934/status:State:	S (sleeping)<br />
ebergen@kamet:(/proc/20924/task) fg<br />
~/bad_trace 20924<br />
</tt></p>
<p>bad_trace resumes and exits without detaching from the traced process. To enable an admin to kill the traced process linux does some cleanup work by changing it&#8217;s state from traced to stopped. Now we can send signals to the thread group and they will be able to respond. </p>
<p><tt><br />
ebergen@kamet:(/proc/20924/task) grep State */status<br />
20924/status:State:	T (stopped)<br />
20926/status:State:	S (sleeping)<br />
20927/status:State:	S (sleeping)<br />
20928/status:State:	S (sleeping)<br />
20929/status:State:	S (sleeping)<br />
20931/status:State:	S (sleeping)<br />
20932/status:State:	S (sleeping)<br />
20933/status:State:	S (sleeping)<br />
20934/status:State:	S (sleeping)<br />
</tt></p>
<p>Naturally we don&#8217;t want the thread group leader stopped if everything is OK so I send it a continue signal to resume operation. This is where things get weird.</p>
<p><tt><br />
ebergen@kamet:(/proc/20924/task) kill -CONT 20924<br />
</tt></p>
<p>Instead of the thread group leader resuming operation linux decides that it&#8217;s a good idea to stop all threads instead. </p>
<p><tt><br />
ebergen@kamet:(/proc/20924/task) grep State */status<br />
20924/status:State:	T (stopped)<br />
20926/status:State:	T (stopped)<br />
20927/status:State:	T (stopped)<br />
20928/status:State:	T (stopped)<br />
20929/status:State:	T (stopped)<br />
20931/status:State:	T (stopped)<br />
20932/status:State:	T (stopped)<br />
20933/status:State:	T (stopped)<br />
20934/status:State:	T (stopped)<br />
</tt></p>
<p>Sending a second continue signal does the right thing and the process resumes. </p>
<p><tt><br />
ebergen@kamet:(/proc/20924/task) kill -CONT 20924<br />
ebergen@kamet:(/proc/20924/task) grep State */status<br />
20924/status:State:	S (sleeping)<br />
20926/status:State:	S (sleeping)<br />
20927/status:State:	S (sleeping)<br />
20928/status:State:	S (sleeping)<br />
20929/status:State:	S (sleeping)<br />
20931/status:State:	S (sleeping)<br />
20932/status:State:	S (sleeping)<br />
20933/status:State:	S (sleeping)<br />
20934/status:State:	S (sleeping)<br />
</tt></p>
<p>I did some digging in the kernel and didn&#8217;t see any specific reason for this behavior. I suspect it&#8217;s a kernel bug that has never been uncovered because tracing a single thread of a threaded process isn&#8217;t a very common operation. </p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2008/06/25/ptrace-on-threads-and-linux-signal-handling-issues/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Splitting flush logs command</title>
		<link>http://ebergen.net/wordpress/2008/05/19/splitting-flush-logs-command/</link>
		<comments>http://ebergen.net/wordpress/2008/05/19/splitting-flush-logs-command/#comments</comments>
		<pubDate>Tue, 20 May 2008 02:21:17 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/?p=179</guid>
		<description><![CDATA[Last week I was working with a client that rediscovered a bug where setting expire_logs_days and issuing a flush logs causes the server to crash. It&#8217;s MySQL Bug #17733 if you want to have a look. Seeing MySQL crash was enough inspiration to fix something that I and others have wanted to fix in MySQL [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I was working with a client that rediscovered a bug where setting expire_logs_days and issuing a flush logs causes the server to crash. It&#8217;s <a href="http://bugs.mysql.com/bug.php?id=17733">MySQL Bug #17733</a> if you want to have a look.  Seeing MySQL crash was enough inspiration to fix something that I and others have wanted to fix in MySQL for years. </p>
<p>Currently a flush logs command tries to flush all of the following logs in order:</p>
<ul>
<li>General Log</li>
<li>Slow Query Log</li>
<li>Binary Log</li>
<li>Relay Log</li>
<li>Store Engine Logs (If available)</li>
<li>Error Log</li>
</ul>
<p>The reason I wanted to fix this is because my client was issuing a flush logs to rotate the error log on a server with no replication. The crash was caused by replication. With individual flush logs it&#8217;s less likely for this to happen again in the future. People can simply issue a query for the log they want to flush. The new commands flush logs named in the command. They are:</p>
<ul>
<li>flush general log;</li>
<li>flush slow log;</li>
<li>flush binary log;</li>
<li>flush relay log;</li>
<li>flush engine logs;</li>
<li>flush error log; </li>
</ul>
<p>The words log and logs are interchangeable. The query &#8220;flush general log&#8221; is just as valid as &#8220;flush general logs&#8221; even though there is only one log. I submitted the patch as a fix for <a href="http://bugs.mysql.com/bug.php?id=14104">MySQL Bug #14104</a>. </p>
<p>The patch, <a href="http://ebergen.net/patches/flush_logs.patch">flush_logs.patch</a> was diffed against 6.0.4 but also applies on 5.1.24. </p>
<p>Rotation for different log files isn&#8217;t uniform. Rotating the slow log simply closes and opens it. I&#8217;m planning to write a second patch that rotates log files using the same numbered scheme as binary logs. This fixes the rotation for slow and general log as well as eliminating the annoying issue of error logs being destroyed after they are rotated to foo.log-old. </p>
<p>This patch hasn&#8217;t been accepted or committed yet so if you have any suggestions on how to make it better please let me know.  </p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2008/05/19/splitting-flush-logs-command/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Parallels CD Jacket</title>
		<link>http://ebergen.net/wordpress/2007/07/10/parallels-cd-jacket/</link>
		<comments>http://ebergen.net/wordpress/2007/07/10/parallels-cd-jacket/#comments</comments>
		<pubDate>Tue, 10 Jul 2007 19:18:46 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/2007/07/10/parallels-cd-jacket/</guid>
		<description><![CDATA[&#8220;The following serial number must be entered to activate your software. We recommend writing the number inside your manual for future reference.&#8221; Why didn&#8217;t you just put the sticker with the serial number on the manual?]]></description>
			<content:encoded><![CDATA[<p>&#8220;The following serial number must be entered to activate your software. We recommend writing the number inside your manual for future reference.&#8221; </p>
<p>Why didn&#8217;t you just put the sticker with the serial number on the manual?</p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2007/07/10/parallels-cd-jacket/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mytop support for 5.0</title>
		<link>http://ebergen.net/wordpress/2006/12/09/mytop-support-for-50/</link>
		<comments>http://ebergen.net/wordpress/2006/12/09/mytop-support-for-50/#comments</comments>
		<pubDate>Sat, 09 Dec 2006 06:25:08 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/2006/12/09/mytop-support-for-50/</guid>
		<description><![CDATA[In 5.0 the ability to show status for local or session variables. Unfortunately the default for this command is session instead of global (like the old method). This breaks many existing programs such as mytop. Here is a patch for mytop 1.4 that makes it aware of the 5.0 style show status. Here is my [...]]]></description>
			<content:encoded><![CDATA[<p>In 5.0 the ability to show status for local or session variables. Unfortunately the default for this command is session instead of global (like the old method). This breaks many existing programs such as <a title="mytop" href="http://jeremy.zawodny.com/mysql/mytop/">mytop</a>. Here is a <a title="mytop patch for mysql 5.0" href="http://ebergen.net/patches/mytop_five_o.patch">patch</a> for mytop 1.4 that makes it aware of the 5.0 style show status.</p>
<p>Here is my rant about changing the default value which I won&#8217;t repeat here.</p>
<p><a title="Show @&#038;!# status again!" href="http://ebergen.net/wordpress/2006/09/22/show-status-again/">Show @&#038;!# status again! </a></p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2006/12/09/mytop-support-for-50/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHfhghasdbasdf</title>
		<link>http://ebergen.net/wordpress/2006/09/10/phfhghasdbasdf/</link>
		<comments>http://ebergen.net/wordpress/2006/09/10/phfhghasdbasdf/#comments</comments>
		<pubDate>Mon, 11 Sep 2006 03:54:03 +0000</pubDate>
		<dc:creator>Eric Bergen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ebergen.net/wordpress/2006/09/10/phfhghasdbasdf/</guid>
		<description><![CDATA[I&#8217;ve tried to write 4 different blog entries tonight. After driving 700 miles today I can&#8217;t complete any of them. Until my brain recovers these blog entries will join several other ideas that will exist as brain crack until I can get enough rest to form a complete thought.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve tried to write 4 different blog entries tonight. After driving 700 miles today I can&#8217;t complete any of them. Until my brain recovers these blog entries will join several other ideas that will exist as <a title="brain crack" href="http://www.zefrank.com/theshow/archives/2006/07/071106.html">brain crack</a> until I can get enough rest to form a complete thought.</p>
]]></content:encoded>
			<wfw:commentRss>http://ebergen.net/wordpress/2006/09/10/phfhghasdbasdf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

