<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:content="http://purl.org/rss/1.0/modules/content/">

<channel>
  <title>Planet MySQL</title>
  <link>http://www.planetmysql.org/</link>
  <pubDate>Wed, 16 May 2012 11:00:01 +0000</pubDate>
  <language>en</language>
  <description>Planet MySQL - http://www.planetmysql.org/</description>

  <item>
    <title>MySQL Cluster 7.2.7 achieves 1BN update transactions per minute</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-14455177.post-5632482448415783656</guid>
    <link>http://mikaelronstrom.blogspot.com/2012/05/mysql-cluster-727-achieves-1bn-update.html</link>
    <description>In MySQL Cluster there is a limiting factor in the receive threads that limits our update performance to about 0.5M update transactions per node group per second (usually 2 nodes per node group). In MySQL Cluster 7.2.7 we have removed most of this bottleneck and can now achieve 3x as many update transactions. We're reaching about 1.5M updates per node group per second. On a 30-node configuration we achieved 19.5M update transactions per second which corresponds to 1.17BN updates per minute. This means we achieve almost linear increase of update performance all the way to 30 data nodes.The benchmarks were executed using the benchmark scripts dbt2-0.37.50 available at dev.mysql.com, the benchmark program is the flexAsynch program mentioned in some of my earlier blogs. We used 8 LQH threads per data node. </description>
    <content:encoded><![CDATA[<div dir="ltr" trbidi="on">In MySQL Cluster there is a limiting factor in the receive threads that limits our update performance to about 0.5M update transactions per node group per second (usually 2 nodes per node group). In MySQL Cluster 7.2.7 we have removed most of this bottleneck and can now achieve 3x as many update transactions. We're reaching about 1.5M updates per node group per second. On a 30-node configuration we achieved 19.5M update transactions per second which corresponds to 1.17BN updates per minute. This means we achieve almost linear increase of update performance all the way to 30 data nodes.<br /><br />The benchmarks were executed using the benchmark scripts dbt2-0.37.50 available at dev.mysql.com, the benchmark program is the flexAsynch program mentioned in some of my earlier blogs. We used 8 LQH threads per data node. </div><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/14455177-5632482448415783656?l=mikaelronstrom.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33246&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33246&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 16 May 2012 07:21:00 +0000</pubDate>
    <dc:creator>Mikael Ronstr&amp;ouml;m</dc:creator>
  </item>

  <item>
    <title>Stalls during DDL</title>
    <guid isPermaLink="false">http://www.facebook.com/note.php?note_id=10150783146150933</guid>
    <link>http://www.facebook.com/note.php?note_id=10150783146150933</link>
    <description>InnoDB locks the buffer pool mutex and scans the LRU to remove pages when DROP TABLE is done for a table that uses innodb_file_per_table. If you read the source you might notice that it scans the LRU twice, once in buf_LRU_drop_page_hash_for_tablespace and then again in buf_LRU_invalidate_tablespace. Locking the buffer pool mutex and scanning the LRU isn&amp;#039;t cheap when the buffer pool is large. It takes ~1 second on servers I use and that is too much as nothing gets done during that time by other threads. I changed InnoDB to remove one of the LRU scans and reduced the stall in half. However that was not good enough. The next step was to avoid any LRU scan during DROP TABLE. Several bugs have been filed for this but the primary ones are bug 51325 and bug 64284. To fix bug 51325 InnoDB in trunk and/or MySQL 5.6 has been changed to scan the flush list rather than the LRU. If your server has 10% dirty pages, then the stall should be reduced by a factor of 10. While discussing bug 51325 with the InnoDB engineering team I worked on my version of a fix that avoids scanning either the LRU or the flush list. I tested the performance of this change by using sysbench with 8 client threads. The test was run in three modes as describe below. The results show that the fix is better at preserving performance during DROP TABLE.no drop table - without DROP TABLE running concurrentlyfast drop table - with the fix from the Facebook patch and another connection running DROP TABLE concurrent with queriesslow drop table -without the fix from the Facebook patch and another connection running DROP TABLE concurrent with queries</description>
    <content:encoded><![CDATA[<div><p>InnoDB locks the buffer pool mutex and scans the LRU to remove pages when DROP TABLE is done for a table that uses <a href="http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_file_per_table" onmousedown="UntrustedLink.bootstrap($(this), &quot;TAQHkRTWj&quot;, event, bagof(null));" rel="nofollow" target="_blank">innodb_file_per_table</a>. If you read the source you might notice that it scans the LRU twice, once in buf_LRU_drop_page_hash_for_tablespace and then again in buf_LRU_invalidate_tablespace. Locking the buffer pool mutex and scanning the LRU isn&#039;t cheap when the buffer pool is large. It takes ~1 second on servers I use and that is too much as nothing gets done during that time by other threads.</p><p> </p><p>I changed InnoDB to remove one of the LRU scans and reduced the stall in half. However that was not good enough. The next step was to avoid any LRU scan during DROP TABLE. Several bugs have been filed for this but the primary ones are <a href="http://bugs.mysql.com/bug.php?id=51325" onmousedown="UntrustedLink.bootstrap($(this), &quot;MAQFHXXF0&quot;, event, bagof(null));" rel="nofollow" target="_blank">bug 51325</a> and <a href="http://bugs.mysql.com/bug.php?id=64284" onmousedown="UntrustedLink.bootstrap($(this), &quot;uAQF_3tx8&quot;, event, bagof(null));" rel="nofollow" target="_blank">bug 64284</a>. To fix bug 51325 InnoDB in trunk and/or MySQL 5.6 has been changed to scan the flush list rather than the LRU. If your server has 10% dirty pages, then the stall should be reduced by a factor of 10. While discussing bug 51325 with the InnoDB engineering team I worked on my version of a fix that avoids scanning either the LRU or the flush list.</p><p> </p><p>I tested the performance of this change by using sysbench with 8 client threads. The test was run in three modes as describe below. The results show that the fix is better at preserving performance during DROP TABLE.</p><ul><li><strong>no drop table</strong> - without DROP TABLE running concurrently</li><li><strong>fast drop table</strong> - with the fix from the Facebook patch and another connection running DROP TABLE concurrent with queries</li><li><strong>slow drop table</strong> -without the fix from the Facebook patch and another connection running DROP TABLE concurrent with queries</li></ul><p><span><img class="photo_img img" src="http://sphotos.xx.fbcdn.net/hphotos-snc7/385695_10150808105966696_102841356695_10322713_1793896791_n.jpg" alt="" /><span></span></span></p></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33245&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33245&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Tue, 15 May 2012 18:23:44 +0000</pubDate>
    <dc:creator>Mark Callaghan</dc:creator>
  </item>

  <item>
    <title>Announcing the Explain Analyzer</title>
    <guid isPermaLink="false">http://blog.montyprogram.com/?p=1022</guid>
    <link>http://blog.montyprogram.com/announcing-the-explain-analyzer/</link>
    <description>The explain statement can be an important tool for understanding how a query is being executed and what you can do to make it run better.  Although the output of EXPLAIN is relatively straightforward it can be confusing to inexperienced users or can be mangled by terminal wrapping.
To help with these problems as well as provide a pastebin for MariaDB developers to share explains during development we created The MariaDB/MySQL Explain Analyzer. This tool:

Helps unmangle explains (both vertical and tabular format)
Displays explains in an easy-to-read format.
Highlights and provides explanations for some terms.
Links to KB articles for different optimization techniques.
(Optionally) Allows you to save the explain for sharing.

This is the first release so there are still improvements to make. If you have any suggestions, feature requests or bug reports please let us know.
For more information, please see this KB article.
&amp;nbsp;</description>
    <content:encoded><![CDATA[<p>The explain statement can be an important tool for understanding how a query is being executed and what you can do to make it run better.  Although the output of EXPLAIN is relatively straightforward it can be confusing to inexperienced users or can be mangled by terminal wrapping.</p>
<p>To help with these problems as well as provide a pastebin for MariaDB developers to share explains during development we created <a title="The MariaDB / MySQL Explain Analyzer" href="http://mariadb.org/explain_analyzer/">The MariaDB/MySQL Explain Analyzer</a>. This tool:</p>
<ol>
<li>Helps unmangle explains (both vertical and tabular format)</li>
<li>Displays explains in an easy-to-read format.</li>
<li>Highlights and provides explanations for some terms.</li>
<li>Links to <a title="Knowledgebase" href="http://kb.askmonty.org">KB</a> articles for different optimization techniques.</li>
<li>(Optionally) Allows you to save the explain for sharing.</li>
</ol>
<p>This is the first release so there are still improvements to make. If you have any suggestions, feature requests or bug reports please let us know.</p>
<p>For more information, please see <a href="http://kb.askmonty.org/en/explain-analyzer">this KB article</a>.</p>
<p>&nbsp;</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33244&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33244&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Tue, 15 May 2012 15:48:11 +0000</pubDate>
    <dc:creator>Monty Program Group Blog</dc:creator>
    <category>General</category>
  </item>

  <item>
    <title>Some throttling for PECL/mysqlnd_ms 1.4</title>
    <guid isPermaLink="false">http://blog.ulf-wendel.de/2012/some-throttling-for-peclmysqlnd_ms-14/</guid>
    <link>http://blog.ulf-wendel.de/2012/some-throttling-for-peclmysqlnd_ms-14/</link>
    <description>
Users of MySQL Replication sometimes throttle client requests to give slaves time to catch up to the master. PECL/mysqlnd_ms 1.4, the current development version, features some throttling through the quality-of-service filter and global transaction identifier (GTID). Both the plugins client-side GTID emulation and the MySQL 5.6 built-in GTID feature can be used to slow down PHP MySQL requests, if wanted.

	How its done
	
The replication plugin has a neat feature called quality-of-service filter. If, for example, the quality of service you need from a MySQL Replication cluster is &amp;quot;read your writes&amp;quot;, you call mysqlnd_ms_set_qos($connection, MYSQLND_MS_QOS_CONSISTENCY_SESSION). This instructs the plugin to either use a master or a slave, that has replicated your writes already, for all further reads. The plugin takes care of picking an appropriate cluster node. Once you are done with &amp;quot;read your writes&amp;quot; you can relax the service quality to make node selection faster.

	
By default, MYSQLND_MS_QOS_CONSISTENCY_SESSION will enforce reading from the master. This is undesired as it increases the load on the master. However, before the introduction of global transaction identifiers, there was no safe way of knowing whether a slave had replicated a certain update already or not.

	
Using either the plugins GTID emulation or the MySQL 5.6 build-in GTID feature, one can reliably check the up-to-date status of a slave using a SQL SELECT statement.  GTIDs are some kind of unique transaction sequence numbers. If you know the transaction sequence number of a write operation, you can check whether it has been replicated using a statement like, for example, SELECT GTID_SUBSET('gtid_of_write', @@GLOBAL.GTID_DONE) AS trx_id FROM DUAL. Please, check my previous posts for a more precise description of the GTID feature. This statement will check the replication status and return immediately.
	SQL_THREAD_WAIT_AFTER_GTIDS(string gtids [, timeout])
	
Alternatively, a MySQL 5.6 user can issue SELECT SQL_THREAD_WAIT_AFTER_GTIDS('gtid_of_write') which will block until either the slave has replicated the write in question or the statement times out. This is great to throttle clients and prevent them to send new updates before the slaves have caught up. This is what some throttling is about. You can control which logic PECL/mysqlnd_ms shall use when searching for an up-to-date slave.

	
	
Strictly speaking, you could do it in 1.3 already, if using MySQL 5.6, which is not GA yet. GTIDs are opaque to the plugin. The configuration contains a SQL statement to fetch gtid_of_write and one to check if gtid_of_write has been replicated already. You have been free to either use  SQL_THREAD_WAIT_AFTER_GTIDS or not for those config settings.

	The new bit
	
New is a wait_for_gtid_timeout setting that can be used with the GTID emulation. If wait_for_gtid_timeout is set, the plugin will poll a slaves state for wait_for_gtid_timeout seconds regardless of the SQL statement configured. The plugin first runs the SQL statement to check if gtid_of_write has been replicated already. If not, it checks if there is time left for another poll attempt, sleeps for second and polls the status again.

	
All this is done transparently in the background. All the application does is formulate its quality of service needs.

	Throttling makes synchronization costs visible
	
Throttling client requests should not be understood as a hack. MySQL Replication happens to be a lazy primary copy system. All updates must be performed on the primary (master). Synchronization of secondaries (slaves) is lazy. Update transactions are finished once the primary has finished them.  An update transaction never waits for secondaries to catch up. This is an easy to implement, often fast and simple approach.

	
The drawbacks are temporarily stale data on the secondaries and limited gains in availability over a single server.

	
Clients get confirmation for update transactions as soon as they are finished on the primary. As soon as they are saved on just one server. There is no guarantee that the transaction ever makes it to a secondary. In the unlikely worst case, the primary crashes in an unrecoverable manner and transactions are lost before being replicated. Thus, little gain over a single server. If you don&amp;#8217;t want that, you need eager synchronization. This is what MySQL Cluster offers, if you want it. For eager synchronization one needs to slow down updates and wait for one or all replicas to confirm the update. If updating one secondary is all you need, go for MySQL Semisynchronous Replication.

	
It may not be technically valid comparison, however, the slow down and wait reminds me of throttling. MySQL lets you choose whether you want to do the wait on demand and on the client side (MySQL Replication: lazy synchronization) or built-in to the distributed system (MySQL Cluster: eager synchronization). Putting all this in a matrix shows the wide range of  database replication options that MySQL has to offer.

	
	
	&amp;nbsp;
	Update: where
	
	
	&amp;nbsp;
	Primary copy
	Update anywhere
	
	
	Synch.:when
	Eager
	(MySQL Semisynchronous Replication - one secondary eager, rest lazy)
	MySQL Cluster
	
	
	Lazy
	MySQL Replication
	(MySQL Cluster WAN mirror using MySQL Replication - automatic conflict detection)
	
	
	Happy hacking!
	
@Ulf_Wendel&amp;nbsp;
</description>
    <content:encoded><![CDATA[<p>
Users of MySQL Replication sometimes throttle client requests to give slaves time to catch up to the master. <a href="http://www.php.net/mysqlnd_ms">PECL/mysqlnd_ms</a> 1.4, the current development version, features some throttling through the quality-of-service filter and global transaction identifier (GTID). Both the plugins <a href="http://de3.php.net/manual/de/mysqlnd-ms.gtid.php">client-side GTID emulation</a> and the <a href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html">MySQL 5.6 built-in GTID feature</a> can be used to slow down PHP MySQL requests, if wanted.
</p>
	<h3>How its done</h3>
	<p>
The replication plugin has a neat feature called <a href="http://de3.php.net/manual/de/mysqlnd-ms.qos-consistency.php">quality-of-service</a> filter. If, for example, the quality of service you need from a MySQL Replication cluster is &quot;read your writes&quot;, you call <code><a href="http://de3.php.net/mysqlnd_ms_set_qos">mysqlnd_ms_set_qos</a>($connection, MYSQLND_MS_QOS_CONSISTENCY_SESSION)</code>. This instructs the plugin to either use a master or a slave, that has replicated your writes already, for all further reads. The plugin takes care of picking an appropriate cluster node. Once you are done with &quot;read your writes&quot; you can relax the service quality to make node selection faster.
</p>
	<p>
By default, <code>MYSQLND_MS_QOS_CONSISTENCY_SESSION</code> will enforce reading from the master. This is undesired as it increases the load on the master. However, before the introduction of global transaction identifiers, there was no safe way of knowing whether a slave had replicated a certain update already or not.
</p>
	<p>
Using either the plugins GTID emulation or the MySQL 5.6 build-in GTID feature, one can reliably check the up-to-date status of a slave using a SQL <code>SELECT</code> statement.  GTIDs are some kind of unique transaction sequence numbers. If you know the transaction sequence number of a write operation, you can check whether it has been replicated using a statement like, for example, <code>SELECT GTID_SUBSET('gtid_of_write', @@GLOBAL.GTID_DONE) AS trx_id FROM DUAL</code>. Please, check my previous posts for a more precise description of the GTID feature. This statement will check the replication status and return immediately.</p>
	<p><h3>SQL_THREAD_WAIT_AFTER_GTIDS(string gtids [, timeout])</h3>
	<p>
Alternatively, a MySQL 5.6 user can issue <code>SELECT SQL_THREAD_WAIT_AFTER_GTIDS('gtid_of_write')</code> which will block until either the slave has replicated the write in question or the statement times out. This is great to throttle clients and prevent them to send new updates before the slaves have caught up. This is what <em>some</em> throttling is about. You can control which logic PECL/mysqlnd_ms shall use when searching for an up-to-date slave.
</p>
	<p><a></a></p>
	<p>
Strictly speaking, you could do it in 1.3 already, if using MySQL 5.6, which is not GA yet. GTIDs are opaque to the plugin. The configuration contains a SQL statement to fetch <code>gtid_of_write</code> and one to check if <code>gtid_of_write</code> has been replicated already. You have been free to either use  <code>SQL_THREAD_WAIT_AFTER_GTIDS</code> or not for those config settings.
</p>
	<h3>The new bit</h3>
	<p>
New is a <code>wait_for_gtid_timeout</code> setting that can be used with the GTID emulation. If <code>wait_for_gtid_timeout</code> is set, the plugin will poll a slaves state for <code>wait_for_gtid_timeout</code> seconds regardless of the SQL statement configured. The plugin first runs the SQL statement to check if <code>gtid_of_write</code> has been replicated already. If not, it checks if there is time left for another poll attempt, sleeps for second and polls the status again.
</p>
	<p>
All this is done transparently in the background. All the application does is formulate its quality of service needs.
</p>
	<h3>Throttling makes synchronization costs visible</h3>
	<p>
Throttling client requests should not be understood as a hack. MySQL Replication happens to be a lazy primary copy system. All updates must be performed on the primary (master). Synchronization of secondaries (slaves) is lazy. Update transactions are finished once the primary has finished them.  An update transaction never waits for secondaries to catch up. This is an easy to implement, often fast and simple approach.
</p>
	<p>
The drawbacks are temporarily stale data on the secondaries and limited gains in availability over a single server.
</p>
	<p>
Clients get confirmation for update transactions as soon as they are finished on the primary. As soon as they are saved on just one server. There is no guarantee that the transaction ever makes it to a secondary. In the unlikely worst case, the primary crashes in an unrecoverable manner and transactions are lost before being replicated. Thus, little gain over a single server. If you don&#8217;t want that, you need eager synchronization. This is what MySQL Cluster offers, if you want it. For eager synchronization one needs to slow down updates and wait for one or all replicas to confirm the update. If updating one secondary is all you need, go for <a href="http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html">MySQL Semisynchronous Replication</a>.
</p>
	<p>
It may not be technically valid comparison, however, the slow down and wait reminds me of throttling. MySQL lets you choose whether you want to do the wait on demand and on the client side (MySQL Replication: lazy synchronization) or built-in to the distributed system (MySQL Cluster: eager synchronization). Putting all this in a matrix shows the wide range of  database replication options that MySQL has to offer.
</p>
	<table border="0" cellspacing="2" cellpadding="2">
	<tr>
	<td colspan="2">&nbsp;</td>
	<th bgcolor="#e0e0e0"  colspan="2" align="center" valign="top">Update: where</th>
	</tr>
	<tr>
	<td colspan="2">&nbsp;</td>
	<th  bgcolor="#e0e0e0" align="center" valign="top">Primary copy</th>
	<th  bgcolor="#e0e0e0" align="center" valign="top">Update anywhere</th>
	</tr>
	<tr>
	<th bgcolor="#e0e0e0" align="center" valign="middle" rowspan="2">Synch.:<br />when</th>
	<th bgcolor="#e0e0e0" align="center" valign="middle">Eager</th>
	<td align="center" valign="top">(MySQL Semisynchronous Replication - one secondary eager, rest lazy)</td>
	<td align="center" valign="top">MySQL Cluster</td>
	</tr>
	<tr bgcolor="#f0f0f0">
	<th  bgcolor="#e0e0e0" align="center" valign="middle">Lazy</th>
	<td align="center" valign="top">MySQL Replication</td>
	<td align="center" valign="top">(MySQL Cluster WAN mirror using MySQL Replication - automatic conflict detection)</td>
	</tr>
	</table>
	<p>Happy hacking!</p>
	<p  align="center">
<a href="http://twitter.com/#!/Ulf_Wendel">@Ulf_Wendel&nbsp;<img src="http://blog.ulf-wendel.de/images/twitter.png" align="middle" alt="Follow me on Twitter" /></a>
</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33239&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33239&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Tue, 15 May 2012 13:11:37 +0000</pubDate>
    <dc:creator>Ulf Wendel</dc:creator>
    <category>PlanetMySQL (english)</category>
    <category>PlanetPHP (english)</category>
  </item>

  <item>
    <title>Finally we have a MySQL User Group in Sweden!</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-8445678881921638771.post-7946446889255301714</guid>
    <link>http://mysql-nordic.blogspot.com/2012/05/finally-we-have-mysql-user-group-in.html</link>
    <description>I have always found it strange that we do not have a MySQL user group in Sweden - this is the country where the MySQL saga started.Therefore I am delighted to announce that since today we have a user group in Sweden and I hope it will be a active one!If you want to join our user group in Sweden, join the group&amp;nbsp;here!</description>
    <content:encoded><![CDATA[<div>I have always found it strange that we do not have a MySQL user group in Sweden - this is the country where the MySQL saga started.</div><div><br /></div><div>Therefore I am delighted to announce that since today we have a user group in Sweden and I hope it will be a active one!</div><div><br /></div><div>If you want to join our user group in Sweden, join the group&nbsp;<a href="http://www.facebook.com/groups/154523608011019/">here</a>!</div><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/8445678881921638771-7946446889255301714?l=mysql-nordic.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33237&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33237&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Tue, 15 May 2012 11:33:00 +0000</pubDate>
    <dc:creator>Ted Wennmark</dc:creator>
  </item>

  <item>
    <title>(My)SQL mistakes. Do you use GROUP BY correctly?</title>
    <guid isPermaLink="false">http://www.dbasquare.com/?p=1790</guid>
    <link>http://www.dbasquare.com/2012/05/15/mysql-mistakes-do-you-use-group-by-correctly/</link>
    <description>Often I see a SQL problem solved incorrectly and I do not mean inefficiently. Simply incorrectly. In many cases the developer remains unaware that they aren&amp;#8217;t getting the results they were expecting or even if a result is correct, it is only by chance, for example because the database engine was smart enough to figure out some non-sense in a query. In a few posts I will try to disclose some of the more common problems.

Aggregate with GROUP BY
Unlike many other database systems, MySQL actually permits that an aggregate query returns columns not used in the aggregation (i.e. not listed in GROUP BY clause). It could be considered as flexibility, but in practice this can easily lead to mistakes if a person that designs queries does not understand how they will be executed. For example, what values an aggregate query returns for a column that wasn&amp;#8217;t part of the grouping key? 

mysql&gt; SELECT user_id, id, COUNT(1) FROM bets WHERE user_id = 99 GROUP BY user_id;
+---------+-------+----------+
| user_id | id    | COUNT(1) |
+---------+-------+----------+
|      99 | 12857 |       12 |
+---------+-------+----------+

id column is a surrogate key and carries a unique value in each and every row, so does 12857 in the query result make any sense, then? Why 12857 and not any other value when user 99 also has eleven other rows in the table? Unless id only had a single value throughout all user&amp;#8217;s rows or I actually wanted to see a single randomly chosen value there, the result is probably not what I needed. GROUP BY does not care about columns that are not part of the aggregate key, so if your query requests them, you should not rely too much on the values they return.
At the same time MySQL comes with a number of aggregate functions. They can process data from the individual rows while GROUP BY is executing. For example I can aggregate by user_id, but also remember and then list all the values from id column:

mysql&gt; SELECT   user_id,
         GROUP_CONCAT(id) _id,
         COUNT(1)
FROM     bets
WHERE    user_id = 99
GROUP BY user_id;
+---------+-------------------------------------------------------------+----------+
| user_id | _id                                                         | COUNT(1) |
+---------+-------------------------------------------------------------+----------+
|      99 | 2857,2856,2858,2851,2852,2855,2853,2854,3201,3200,3262,3261 |       12 |
+---------+-------------------------------------------------------------+----------+

Such result probably makes more sense to my application, because it received the complete information rather than only a random piece.
Sorting an aggregation
What if I needed to grab a few users that most recently made an action based on an activity table? The first thing that comes to my mind:

mysql&gt; SELECT user_id, bet_date FROM bets GROUP BY user_id ORDER BY bet_date DESC LIMIT 3;
+------------+---------------------+
| user_id    | bet_date            |
+------------+---------------------+
|         99 | 2009-12-08 22:51:38 |
|         93 | 2009-11-03 12:39:07 |
|         95 | 2009-09-29 09:23:07 |
+------------+---------------------+

It was easy, wasn&amp;#8217;t it? However, is the result correct? 
ORDER BY is applied after GROUP BY, so it operates on a set that has been already aggregated and not on the individual rows. And how did the aggregation work? For each user GROUP BY collapsed a number of values from bet_date into a single date. This way user 99 received &amp;#8220;2009-12-08 22:51:38&amp;#8243;. But why did it get that particular value? Was it the most recent date among the user&amp;#8217;s records as per ORDER BY caluse? Let&amp;#8217;s examine the raw data:

mysql&gt; SELECT user_id, bet_date FROM bets WHERE user_id = 99 LIMIT 5;
+------------+---------------------+
| user_id    | bet_date            |
+------------+---------------------+
|         99 | 2009-12-08 22:53:20 |
|         99 | 2009-12-08 22:53:09 |
|         99 | 2009-12-08 22:53:37 |
|         99 | 2009-12-08 22:51:38 |
|         99 | 2009-12-08 22:51:58 |
+------------+---------------------+

Just by looking at these rows it becomes clear that &amp;#8220;2009-12-08 22:51:38&amp;#8243; could be anything except the most recent entry, so the answer is &amp;#8216;no&amp;#8217;. So why was it picked for the result? Because MySQL did not evaluate the sort order at the time it was building the aggregation. In fact &amp;#8220;2009-12-08 22:51:38&amp;#8243; came from the very first row that MySQL saw for user 99. In different circumstances the same query on the same data set could return a different value there.
This means the original query did not return the result I expected, because ORDER BY was applied on a limited set of somewhat random values picked by GROUP BY and never saw most values from bet_date.
How to make it work?
I can rely on the aggregate functions again, which gives me some access to the raw values:

mysql&gt; SELECT   user_id,
         MAX(bet_date)
FROM     bets
GROUP BY user_id
ORDER BY MAX(bet_date) DESC
LIMIT    3;
+------------+---------------------+
| user_id    | MAX(bet_date)       |
+------------+---------------------+
|         91 | 2010-05-22 18:49:41 |
|         92 | 2010-05-22 17:18:50 |
|         88 | 2010-05-22 15:14:42 |
+------------+---------------------+

This looks better.
Now, is there a way to learn some other column&amp;#8217;s value for these most recent entries? The following query cannot work correctly. Why? For the reasons that were covered in the first part of this post. game_id will carry any value from the aggregated set, so a value that may or may not be related to the row that has the most recent bet_date:

mysql&gt; SELECT   user_id,
         game_id,
         MAX(bet_date)
FROM     bets
GROUP BY user_id
ORDER BY MAX(bet_date) DESC
LIMIT    3;
+---------+---------+---------------------+
| user_id | game_id | MAX(bet_date)       |
+---------+---------+---------------------+
|      91 |     832 | 2010-05-22 18:49:41 |
|      92 |     831 | 2010-05-22 17:18:50 |
|      88 |     898 | 2010-05-22 15:14:42 |
+---------+---------+---------------------+

A query to solve such problem may need to be a lot more complex and will rarely be very efficient. That is why often it is better to create a summary table for easy querying, instead of running an aggregate query every time such information is required. Here is the example of a query that returns correct result:

mysql&gt; SELECT   _d.user_id,
         bets.game_id,
         _d.bet_date
FROM     (SELECT  user_id,
                  MAX(bet_date) bet_date
         FROM     bets
         GROUP BY user_id
         ORDER BY MAX(bet_date) DESC
         LIMIT    3
         )
         _d
         JOIN bets
USING    (user_id, bet_date)
ORDER BY _d.bet_date DESC;
+---------+---------+---------------------+
| user_id | game_id | bet_date            |
+---------+---------+---------------------+
|      91 |    1004 | 2010-05-22 18:49:41 |
|      92 |    1004 | 2010-05-22 17:18:50 |
|      88 |    1004 | 2010-05-22 15:14:42 |
+---------+---------+---------------------+

Summary
Using GROUP BY can become tricky beyond doing simple aggregations. Due to the relaxed restrictions in MySQL on how the clause can be used in a statement, it is easy to create queries, which do not work correctly. At the same time database does not issue any warnings of a possible problem, so it is entirely up to you to verify whether results are correct and meet your expectations.</description>
    <content:encoded><![CDATA[<p>Often I see a SQL problem solved incorrectly and I do not mean inefficiently. Simply incorrectly. In many cases the developer remains unaware that they aren&#8217;t getting the results they were expecting or even if a result is correct, it is only by chance, for example because the database engine was smart enough to figure out some non-sense in a query. In a few posts I will try to disclose some of the more common problems.</p>
<p><span></span></p>
<h6>Aggregate with <em>GROUP BY</em></h6>
<p>Unlike many other database systems, MySQL actually permits that an aggregate query returns columns not used in the aggregation (i.e. not listed in <em>GROUP BY</em> clause). It could be considered as flexibility, but in practice this can easily lead to mistakes if a person that designs queries does not understand how they will be executed. For example, what values an aggregate query returns for a column that wasn&#8217;t part of the grouping key? </p>
<pre>
mysql> SELECT user_id, id, COUNT(1) FROM bets WHERE user_id = 99 GROUP BY user_id;
+---------+-------+----------+
| user_id | id    | COUNT(1) |
+---------+-------+----------+
|      99 | 12857 |       12 |
+---------+-------+----------+
</pre>
<p><em>id</em> column is a surrogate key and carries a unique value in each and every row, so does <em>12857</em> in the query result make any sense, then? Why <em>12857</em> and not any other value when user <em>99</em> also has eleven other rows in the table? Unless <em>id</em> only had a single value throughout all user&#8217;s rows or I actually wanted to see a single randomly chosen value there, the result is probably not what I needed. <em>GROUP BY</em> does not care about columns that are not part of the aggregate key, so if your query requests them, you should not rely too much on the values they return.</p>
<p>At the same time MySQL comes with a number of <a href="http://dev.mysql.com/doc/refman/5.5/en/group-by-functions.html" title="MySQL aggregate functions" target="_blank" rel="nofollow">aggregate functions</a>. They can process data from the individual rows while GROUP BY is executing. For example I can aggregate by <em>user_id</em>, but also remember and then list all the values from <em>id</em> column:</p>
<pre>
mysql> SELECT   user_id,
         GROUP_CONCAT(id) _id,
         COUNT(1)
FROM     bets
WHERE    user_id = 99
GROUP BY user_id;
+---------+-------------------------------------------------------------+----------+
| user_id | _id                                                         | COUNT(1) |
+---------+-------------------------------------------------------------+----------+
|      99 | 2857,2856,2858,2851,2852,2855,2853,2854,3201,3200,3262,3261 |       12 |
+---------+-------------------------------------------------------------+----------+
</pre>
<p>Such result probably makes more sense to my application, because it received the complete information rather than only a random piece.</p>
<h6>Sorting an aggregation</h6>
<p>What if I needed to grab a few users that most recently made an action based on an activity table? The first thing that comes to my mind:</p>
<pre>
mysql> SELECT user_id, bet_date FROM bets GROUP BY user_id ORDER BY bet_date DESC LIMIT 3;
+------------+---------------------+
| user_id    | bet_date            |
+------------+---------------------+
|         99 | 2009-12-08 22:51:38 |
|         93 | 2009-11-03 12:39:07 |
|         95 | 2009-09-29 09:23:07 |
+------------+---------------------+
</pre>
<p>It was easy, wasn&#8217;t it? However, is the result correct? </p>
<p><em>ORDER BY</em> is applied after <em>GROUP BY</em>, so it operates on a set that has been already aggregated and not on the individual rows. And how did the aggregation work? For each user <em>GROUP BY</em> collapsed a number of values from <em>bet_date</em> into a single date. This way user <em>99</em> received <em>&#8220;2009-12-08 22:51:38&#8243;</em>. But why did it get that particular value? Was it the most recent date among the user&#8217;s records as per <em>ORDER BY</em> caluse? Let&#8217;s examine the raw data:</p>
<pre>
mysql> SELECT user_id, bet_date FROM bets WHERE user_id = 99 LIMIT 5;
+------------+---------------------+
| user_id    | bet_date            |
+------------+---------------------+
|         99 | 2009-12-08 22:53:20 |
|         99 | 2009-12-08 22:53:09 |
|         99 | 2009-12-08 22:53:37 |
|         99 | 2009-12-08 22:51:38 |
|         99 | 2009-12-08 22:51:58 |
+------------+---------------------+
</pre>
<p>Just by looking at these rows it becomes clear that <em>&#8220;2009-12-08 22:51:38&#8243;</em> could be anything except the most recent entry, so the answer is &#8216;no&#8217;. So why was it picked for the result? Because MySQL did not evaluate the sort order at the time it was building the aggregation. In fact <em>&#8220;2009-12-08 22:51:38&#8243;</em> came from the very first row that MySQL saw for user <em>99</em>. In different circumstances the same query on the same data set could return a different value there.</p>
<p>This means the original query did not return the result I expected, because <em>ORDER BY</em> was applied on a limited set of somewhat random values picked by <em>GROUP BY</em> and never saw most values from <em>bet_date</em>.</p>
<p>How to make it work?</p>
<p>I can rely on the aggregate functions again, which gives me some access to the raw values:</p>
<pre>
mysql> SELECT   user_id,
         MAX(bet_date)
FROM     bets
GROUP BY user_id
ORDER BY MAX(bet_date) DESC
LIMIT    3;
+------------+---------------------+
| user_id    | MAX(bet_date)       |
+------------+---------------------+
|         91 | 2010-05-22 18:49:41 |
|         92 | 2010-05-22 17:18:50 |
|         88 | 2010-05-22 15:14:42 |
+------------+---------------------+
</pre>
<p>This looks better.</p>
<p>Now, is there a way to learn some other column&#8217;s value for these most recent entries? The following query cannot work correctly. Why? For the reasons that were covered in the first part of this post. <em>game_id</em> will carry any value from the aggregated set, so a value that may or may not be related to the row that has the most recent <em>bet_date</em>:</p>
<pre>
mysql> SELECT   user_id,
         game_id,
         MAX(bet_date)
FROM     bets
GROUP BY user_id
ORDER BY MAX(bet_date) DESC
LIMIT    3;
+---------+---------+---------------------+
| user_id | game_id | MAX(bet_date)       |
+---------+---------+---------------------+
|      91 |     832 | 2010-05-22 18:49:41 |
|      92 |     831 | 2010-05-22 17:18:50 |
|      88 |     898 | 2010-05-22 15:14:42 |
+---------+---------+---------------------+
</pre>
<p>A query to solve such problem may need to be a lot more complex and will rarely be very efficient. That is why often it is better to create a summary table for easy querying, instead of running an aggregate query every time such information is required. Here is the example of a query that returns correct result:</p>
<pre>
mysql> SELECT   _d.user_id,
         bets.game_id,
         _d.bet_date
FROM     (SELECT  user_id,
                  MAX(bet_date) bet_date
         FROM     bets
         GROUP BY user_id
         ORDER BY MAX(bet_date) DESC
         LIMIT    3
         )
         _d
         JOIN bets
USING    (user_id, bet_date)
ORDER BY _d.bet_date DESC;
+---------+---------+---------------------+
| user_id | game_id | bet_date            |
+---------+---------+---------------------+
|      91 |    1004 | 2010-05-22 18:49:41 |
|      92 |    1004 | 2010-05-22 17:18:50 |
|      88 |    1004 | 2010-05-22 15:14:42 |
+---------+---------+---------------------+
</pre>
<h6>Summary</h6>
<p>Using <em>GROUP BY</em> can become tricky beyond doing simple aggregations. Due to the relaxed restrictions in MySQL on how the clause can be used in a statement, it is easy to create queries, which do not work correctly. At the same time database does not issue any warnings of a possible problem, so it is entirely up to you to verify whether results are correct and meet your expectations.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33236&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33236&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Tue, 15 May 2012 10:59:57 +0000</pubDate>
    <dc:creator>dba square</dc:creator>
    <category>Development with MySQL</category>
    <category>Design</category>
    <category>Query</category>
  </item>

  <item>
    <title>Scale differences between OLTP and Analytics</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-6415786925319620734.post-101650794984121573</guid>
    <link>http://database-scalability.blogspot.com/2012/05/scale-differences-between-oltp-and.html</link>
    <description>In my previous post,http://database-scalability.blogspot.com/2012/05/oltp-vs-analytics.html,&amp;nbsp;I reviewed the differences between OLTP and Analytics databases.Scale challenges are different between those 2 worlds of databases.Scale challenges in the Analytics world are with the growing amounts of data. Most solutions have been leveraging those 3 main aspects: Columnar storage, RAM and parallelism.Columnar storage makes scans and data filtering more precise and focused. After that – it all goes down to the I/O - the faster the I/O is, the faster the query will finish and bring results. Faster disks and also SSD can play good role, but above all: RAM! Specialized Analytics databases (such as Oracle Exadata and Netezza) have TBs of RAM. Then, in order to bring results for queries, data needs to be scanned and filtered, a great fit for parallelism. A big data range is divided into many smaller ranges given to parallel worker threads that each performs his task in parallel, the entire scan will finish in a fraction of the time.In the OLTP, scale challenges are in the growing transaction concurrency throughput and… growing amounts of data. Again?&amp;nbsp;Didn't&amp;nbsp;we just say growing data is the problem of Analytics? Well, today’s OLTP apps are required to hold more data to provide a larger span online functionality. In the last couple of years OLTP data archiving was changed dramatically. OLTP data now covers years and not just days or weeks. Facebook recently launched its “time line” feature (http://www.facebook.com/about/timeline), can you imagine your timeline ends after 1 week? Facebook’s probably world’s largest OLTP database holds data of a billion users for years back. Today all data is required anywhere anytime, right here, right now, online. Many of today’s OLTP databases go well beyond the 1TB line. And what about transaction concurrency throughput? Applications today are bombarded by millions of users shooting transactions from browsers, smartphones, tablets… I personally checked my bank account 3 times today. Why? Because I can…What can be done to solve OLTP scale challenges?In my next post let's start answering this question with understanding why solutions proposed for the Analytics are limited in the OLTP, and start reviewing relevant approaches.Stay tuned, subscribe, get involved!</description>
    <content:encoded><![CDATA[<br />In my previous post,<a href="http://database-scalability.blogspot.com/2012/05/oltp-vs-analytics.html">http://database-scalability.blogspot.com/2012/05/oltp-vs-analytics.html</a>,&nbsp;I reviewed the differences between OLTP and Analytics databases.<br /><br />Scale challenges are different between those 2 worlds of databases.<br /><br /><div><a href="http://1.bp.blogspot.com/-g3T73XdTnZo/T7HM6HI3muI/AAAAAAAAFpY/lZJkxgMQsnM/s1600/OLTP-DW.png" imageanchor="1"><img border="0" height="315" src="http://1.bp.blogspot.com/-g3T73XdTnZo/T7HM6HI3muI/AAAAAAAAFpY/lZJkxgMQsnM/s320/OLTP-DW.png" width="320" /></a></div><br /><br />Scale challenges in the Analytics world are with the growing amounts of data. Most solutions have been leveraging those 3 main aspects: <b><u>Columnar storage, RAM and parallelism</u></b>.<br />Columnar storage makes scans and data filtering more precise and focused. After that – it all goes down to the I/O - the faster the I/O is, the faster the query will finish and bring results. Faster disks and also SSD can play good role, but above all: RAM! Specialized Analytics databases (such as Oracle Exadata and Netezza) have TBs of RAM. Then, in order to bring results for queries, data needs to be scanned and filtered, a great fit for parallelism. A big data range is divided into many smaller ranges given to parallel worker threads that each performs his task in parallel, the entire scan will finish in a fraction of the time.<br /><br />In the OLTP, scale challenges are in the growing transaction concurrency throughput and… growing amounts of data. Again?&nbsp;Didn't&nbsp;we just say growing data is the problem of Analytics? Well, today’s OLTP apps are required to hold more data to provide a larger span online functionality. In the last couple of years OLTP data archiving was changed dramatically. OLTP data now covers years and not just days or weeks. Facebook recently launched its “time line” feature (<a href="http://www.facebook.com/about/timeline">http://www.facebook.com/about/timeline</a>), can you imagine your timeline ends after 1 week? Facebook’s probably world’s largest OLTP database holds data of a billion users for years back. Today all data is required anywhere anytime, right here, right now, online. Many of today’s OLTP databases go well beyond the 1TB line. And what about transaction concurrency throughput? Applications today are bombarded by millions of users shooting transactions from browsers, smartphones, tablets… I personally checked my bank account 3 times today. Why? Because I can…<br /><br />What can be done to solve OLTP scale challenges?<br /><br />In my next post let's start answering this question with understanding why solutions proposed for the Analytics are limited in the OLTP, and start reviewing relevant approaches.<br /><br />Stay tuned, subscribe, get involved!<div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/6415786925319620734-101650794984121573?l=database-scalability.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33240&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33240&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Tue, 15 May 2012 04:08:46 +0000</pubDate>
    <dc:creator>Doron Levari</dc:creator>
    <category>MySQL</category>
    <category>Scale out</category>
    <category>Data warehouse</category>
    <category>OLTP</category>
    <category>Database scalability</category>
    <category>Columnar Storage</category>
    <category>analytics</category>
    <category>Parallelism</category>
  </item>

  <item>
    <title>Why do threads sometimes stay in ‘killed’ state in MySQL?</title>
    <guid isPermaLink="false">http://www.dbasquare.com/?p=1395</guid>
    <link>http://www.dbasquare.com/2012/05/15/why-do-threads-sometimes-stay-in-killed-state-in-mysql/</link>
    <description>Have you ever tried to kill a query, but rather than just go away, it remained among the running ones for an extended period of time? Or perhaps you have noticed some threads makred with killed showing up from time to time and not actually dying. What are these zombies? Why does MySQL sometimes seem to fail to terminate queries quickly? Is there any way to force the kill command to actually work instantaneously? This article sheds some light on it.

Threads and connections
MySQL uses a separate thread for each client connection. A query sent to MySQL is handled by a thread that was previously associated with the connection over which the query arrived. Anyone with sufficient privileges can see the list of currently active threads, along with some additional details, by running SHOW PROCESSLIST command, which returns a table-like view where each connection becomes a separate row:

+-----------+-------------+-------------------+--------+-------------+----------+-------------+---------+
| Id        | User        | Host              | db     | Command     | Time     | State       | Info    |
+-----------+-------------+-------------------+--------+-------------+----------+-------------+---------+
| 827044892 | production  | 10.0.1.100:48596  | proddb | Sleep       |        1 |             |    NULL |
| 827044893 | production  | 10.0.1.100:39181  | proddb | Sleep       |        1 |             |    NULL |
| 827044894 | production  | 10.0.1.100:48598  | proddb | Sleep       |        1 |             |    NULL |
| 827044895 | production  | 10.0.1.100:39183  | proddb | Sleep       |        1 |             |    NULL |

More advanced techniques of dealing with this information are described in the posts titled &amp;#8220;Anohter way to work with MySQL process list&amp;#8221; and &amp;#8220;How to selectively kill queries in MySQL?&amp;#8221;.
Any running query or any existing connection from the list can be terminated by using KILL command.
What actually happens when you run KILL?
The command sytnax is KILL [QUERY | CONNECTION] &amp;lt;thread_id&amp;gt;, where thread_id is the value from the first column of the process list output. The optional argument determines whether only running query or should the entire session be terminated. It defaults to the latter, so specifying CONNECTION is not required.
Running the command doesn&amp;#8217;t actually do anything except for setting a special flag inside the selected thread. Therefore the kill operation doesn&amp;#8217;t happen synchronously with the corresponding request. In many cases it takes some time for a thread or a query to stop. The flag is checked at various stages of statement execution. When it happens exactly, or how frequently, depends on the work a thread is actually doing.
For example:

During ALTER TABLE it is checked before each block of rows is read from the original table while MySQL is rewriting data into a new temporary table. In the process, the temporary table is deleted and the original structure remains unchanged.
For UPDATE and DELETE there is also an additional check after each updated or deleted row. If a query managed to make any changes prior to noticing the request to terminate, they have to be rolled back. Note: if a table&amp;#8217;s storage engine does not support transactions (e.g. MyISAM), the changes cannot be rolled back, so the operation will result in partial update!
SELECT also checks it after reading a block of rows.

Of course, these were just basic examples and the behavior can be different in different situations. It is even possible that some queries will be unkillable in certain circumstances. A case of this happened once while reading from INFORMATION_SCHEMA.INNODB_BUFFER_POOL_PAGES_INDEX table. The database was having performance problems at the time and the query execution basically stopped on a lock somewhere deep inside InnoDB and it never got back to the point where the flag value could be checked again.
Threads stay in killed state for a long time. What does it mean?
Actually, there can be two different cases. If KILL &amp;lt;thread_id&amp;gt; was issued, there would be killed in the process list. KILL QUERY &amp;lt;thread_id&amp;gt; doesn&amp;#8217;t kill a connection, but rather it only stops a running query within a connection, so in that case query end text may appear instead.
What if you see something like this?

+----+------+-----------+------+---------+------+----------+------------------------------------+
| Id | User | Host      | db   | Command | Time | State    | Info                               |
+----+------+-----------+------+---------+------+----------+------------------------------------+
| 10 | root | localhost | NULL | Query   |    0 | NULL     | show processlist                   |
| 14 | root | localhost | NULL | Killed  |   27 | Updating | update testdb.sometable set cc=sqrt(id) |
+----+------+-----------+------+---------+------+----------+------------------------------------+

It can either be an effect of a bug (e.g. Bug #52528), or more likely it means the database is performing some work internally to clean up after a task that was terminated.
There is of course no easy way to confirm if this is a bug. So in order to figure it out, you should rather look for evidence that it is not a bug. That what you see is just the effect of a standard operation, which MySQL has to perform to clean up after a query or a transaction.
Probably the most common reason for a thread to stay with either killed or query end for a longer period of time is waiting for a transaction rollback on InnoDB tables. This sometimes can take a lot of time to complete, especially when hundreds of thousands or millions of changes have to be removed. 
How to verify that?
Check is the output of SHOW ENGINE INNODB STATUS\G. It can simply print the information if there is a rollback currently in progress:

---TRANSACTION 0 10411, ACTIVE 28 sec, process no 15506, OS thread id 140732309711184 rollback
mysql tables in use 1, locked 1
ROLLING BACK 7585 lock struct(s), heap size 751600, undo log entries 798854
MySQL thread id 14, query id 206 localhost root end
update testdb.sometable set cc=sqrt(id)

The example shows how easily the information can be found. If a thread is marked with killed, or with query end, and the InnoDB engine status reports a rollback for the same thread, just wait until it ends.
What if it isn&amp;#8217;t that?
It can be related to removing some temporary table from disk. An ALTER TABLE may need to discard a very large temporary table, while large file removal on some filesystems (e.g. ext3 or ext4) can be rather slow, so it may need a few seconds or sometimes even longer than that. A temporary table can also be created by any DML statement, but usually not nearly as big in size.
It should not usually be necessary as even in the most extreme cases deleting a file should not take more than ten or twenty seconds, but under heavy I/O load it could be much longer, so is there any way to see whether any temporary table were created or not?
In Percona Server or MariaDB you check the contents of INFORMATION_SCHEMA.GLOBAL_TEMPORARY_TABLE and INFORMATION_SCHEMA.TEMPORARY_TABLE. It will only work for manually established temporary tables with CREATE TEMPORARY TABLE statement, not for those created implicitly by MySQL to execute complex queries.

mysql&gt; select * from INFORMATION_SCHEMA.GLOBAL_TEMPORARY_TABLES;
+------------+--------------+------------+--------+-------------------+------------+----------------+-------------+--------------+-------------+-------------+
| SESSION_ID | TABLE_SCHEMA | TABLE_NAME | ENGINE | NAME              | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | INDEX_LENGTH | CREATE_TIME | UPDATE_TIME |
+------------+--------------+------------+--------+-------------------+------------+----------------+-------------+--------------+-------------+-------------+
|   28051622 | test         | tbl        | InnoDB | #sql8c3_1ac08a6_0 |       1265 |             51 |       65536 |            0 | NULL        | NULL        |
+------------+--------------+------------+--------+-------------------+------------+----------------+-------------+--------------+-------------+-------------+

SESSION_ID is the same as the thread identifier in the process list, so you can connect any killed threads to their temporary tables.
The other type of temporary tables cannot be easily traced. Sometimes it&amp;#8217;s possible to spot the information in the SHOW PROCESSLIST output:

mysql&gt; show processlist;
+----------+------+-----------+------+---------+------+----------------------+---------------------------------------------------+
| Id       | User | Host      | db   | Command | Time | State                | Info                                              |
+----------+------+-----------+------+---------+------+----------------------+---------------------------------------------------+
| 1934     | root | localhost | test | Killed  |    4 | Copying to tmp table | INSERT INTO test.tbl SELECT * FROM test.testtable |
..

Sometimes you can check what temporary files the instance keeps open:

server ~ # lsof -c mysqld | grep \#sql
mysqld  5626 mysql  138u   REG              253,1       1024 43843585  /vol/vol1/mysql/#sql_95fa_0.MYI
mysqld  5626 mysql  139u   REG              253,1  227262885 43843605  /vol/vol1/mysql/#sql_95fa_0.MYD

The colored value is the file&amp;#8217;s size. These may help you to make an assumption that database could be removing a temporary table.
Conclusions
From time to time it may be normal to see a database thread that was killed, but didn&amp;#8217;t die immediately, or a query that can&amp;#8217;t seem to end. The real operation is not be performed synchronously with the kill command and afterwards MySQL may still need some time to clean things up properly. 
No matter what the real cause is, it is impossible to get rid of such hanging threads without a database restart. They should, however, simply be allowed to go away on their own. 
There is also no way of forcing a kill that would execute instantly like kill -9 &amp;lt;pid&amp;gt; in Unix systems.</description>
    <content:encoded><![CDATA[<p>Have you ever tried to kill a query, but rather than just go away, it remained among the running ones for an extended period of time? Or perhaps you have noticed some threads makred with <em>killed</em> showing up from time to time and not actually dying. What are these zombies? Why does MySQL sometimes seem to fail to terminate queries quickly? Is there any way to force the kill command to actually work instantaneously? This article sheds some light on it.</p>
<p><span></span></p>
<h6>Threads and connections</h6>
<p>MySQL uses a separate thread for each client connection. A query sent to MySQL is handled by a thread that was previously associated with the connection over which the query arrived. Anyone with sufficient privileges can see the list of currently active threads, along with some additional details, by running <em>SHOW PROCESSLIST</em> command, which returns a table-like view where each connection becomes a separate row:</p>
<pre>
+-----------+-------------+-------------------+--------+-------------+----------+-------------+---------+
| Id        | User        | Host              | db     | Command     | Time     | State       | Info    |
+-----------+-------------+-------------------+--------+-------------+----------+-------------+---------+
| <span>827044892</span> | production  | 10.0.1.100:48596  | proddb | Sleep       |        1 |             |    NULL |
| <span>827044893</span> | production  | 10.0.1.100:39181  | proddb | Sleep       |        1 |             |    NULL |
| <span>827044894</span> | production  | 10.0.1.100:48598  | proddb | Sleep       |        1 |             |    NULL |
| <span>827044895</span> | production  | 10.0.1.100:39183  | proddb | Sleep       |        1 |             |    NULL |
</pre>
<p><small>More advanced techniques of dealing with this information are described in the posts titled <a href="http://www.dbasquare.com/2012/04/04/anohter-way-to-work-with-mysql-process-list/" title="Anohter way to work with MySQL process list" target="_blank">&#8220;Anohter way to work with MySQL process list&#8221;</a> and <a href="http://www.dbasquare.com/2012/04/04/how-to-selectively-kill-queries-in-mysql/" title="How to selectively kill queries in MySQL?" target="_blank">&#8220;How to selectively kill queries in MySQL?&#8221;</a>.</small></p>
<p>Any running query or any existing connection from the list <strong>can be terminated</strong> by using <em>KILL</em> command.</p>
<h6>What actually happens when you run <em>KILL</em>?</h6>
<p>The command sytnax is <em>KILL [QUERY | CONNECTION] &lt;thread_id&gt;</em>, where <em>thread_id</em> is the value from the first column of the process list output. The optional argument determines whether only running query or should the entire session be terminated. It defaults to the latter, so specifying <em>CONNECTION</em> is not required.</p>
<p>Running the command doesn&#8217;t actually do anything except for setting a special flag inside the selected thread. Therefore the kill operation <strong>doesn&#8217;t happen synchronously with the corresponding request</strong>. In many cases it takes some time for a thread or a query to stop. The flag is checked at various stages of statement execution. When it happens exactly, or how frequently, depends on the work a thread is actually doing.</p>
<p>For example:</p>
<ul>
<li>During <em>ALTER TABLE</em> it is checked before each block of rows is read from the original table while MySQL is rewriting data into a new temporary table. In the process, the temporary table is deleted and the original structure remains unchanged.</li>
<li>For <em>UPDATE</em> and <em>DELETE</em> there is also an additional check after each updated or deleted row. If a query managed to make any changes prior to noticing the request to terminate, they have to be rolled back. <em>Note: if a table&#8217;s storage engine does not support transactions (e.g. MyISAM), the changes cannot be rolled back, so the operation will result in partial update!</em>
<li><em>SELECT</em> also checks it after reading a block of rows.
</ul>
<p>Of course, these were just basic examples and the behavior can be different in different situations. It is even possible that some queries will be <em>unkillable</em> in certain circumstances. A case of this happened once while reading from <em>INFORMATION_SCHEMA.INNODB_BUFFER_POOL_PAGES_INDEX</em> table. The database was having performance problems at the time and the query execution basically stopped on a lock somewhere deep inside InnoDB and it never got back to the point where the flag value could be checked again.</p>
<h6>Threads stay in <em>killed</em> state for a long time. What does it mean?</h6>
<p>Actually, there can be two different cases. If <em>KILL &lt;thread_id&gt;</em> was issued, there would be <em>killed</em> in the process list. <em>KILL QUERY &lt;thread_id&gt;</em> doesn&#8217;t kill a connection, but rather it only stops a running query within a connection, so in that case <em>query end</em> text may appear instead.</p>
<p>What if you see something like this?</p>
<pre>
+----+------+-----------+------+---------+------+----------+------------------------------------+
| Id | User | Host      | db   | Command | Time | State    | Info                               |
+----+------+-----------+------+---------+------+----------+------------------------------------+
| 10 | root | localhost | NULL | Query   |    0 | NULL     | show processlist                   |
| <span>14</span> | root | localhost | NULL | <span>Killed</span>  |   27 | Updating | update testdb.sometable set cc=sqrt(id) |
+----+------+-----------+------+---------+------+----------+------------------------------------+
</pre>
<p>It can either be an effect of a bug (e.g. <a href="http://bugs.mysql.com/bug.php?id=52528" title="Bug #52528" target="_blank" rel="nofollow">Bug #52528</a>), or more likely it means the database is <strong>performing some work internally</strong> to clean up after a task that was terminated.</p>
<p>There is of course no easy way to confirm if this is a bug. So in order to figure it out, you should rather look for evidence that it is not a bug. That what you see is just the effect of a standard operation, which MySQL has to perform to clean up after a query or a transaction.</p>
<p>Probably the most common reason for a thread to stay with either <em>killed</em> or <em>query end</em> for a longer period of time is <strong>waiting for a transaction rollback</strong> on InnoDB tables. This sometimes can take a lot of time to complete, especially when hundreds of thousands or millions of changes have to be removed. </p>
<p>How to verify that?</p>
<p>Check is the output of <em>SHOW ENGINE INNODB STATUS\G</em>. It can simply print the information if there is a rollback currently in progress:</p>
<pre>
---TRANSACTION 0 10411, ACTIVE 28 sec, process no 15506, OS thread id 140732309711184 rollback
mysql tables in use 1, locked 1
<span>ROLLING BACK</span> 7585 lock struct(s), heap size 751600, undo log entries 798854
<span>MySQL thread id 14</span>, query id 206 localhost root end
update testdb.sometable set cc=sqrt(id)
</pre>
<p>The example shows how easily the information can be found. If a thread is marked with <em>killed</em>, or with <em>query end</em>, and the InnoDB engine status reports a rollback for the same thread, just <strong>wait until it ends</strong>.</p>
<p>What if it isn&#8217;t that?</p>
<p>It can be related to <strong>removing some temporary table from disk</strong>. An <em>ALTER TABLE</em> may need to discard a very large temporary table, while large file removal on some filesystems (e.g. <em>ext3</em> or <em>ext4</em>) can be rather slow, so it may need a few seconds or sometimes even longer than that. A temporary table can also be created by any DML statement, but usually not nearly as big in size.</p>
<p>It should not usually be necessary as even in the most extreme cases deleting a file should not take more than ten or twenty seconds, but under heavy I/O load it could be much longer, so is there any way to see whether any temporary table were created or not?</p>
<p>In <em>Percona Server</em> or <em>MariaDB</em> you check the contents of <em>INFORMATION_SCHEMA.GLOBAL_TEMPORARY_TABLE</em> and <em>INFORMATION_SCHEMA.TEMPORARY_TABLE</em>. It will only work for manually established temporary tables with <em>CREATE TEMPORARY TABLE</em> statement, not for those created implicitly by MySQL to execute complex queries.</p>
<pre>
mysql> select * from INFORMATION_SCHEMA.GLOBAL_TEMPORARY_TABLES;</code>
+------------+--------------+------------+--------+-------------------+------------+----------------+-------------+--------------+-------------+-------------+
| SESSION_ID | TABLE_SCHEMA | TABLE_NAME | ENGINE | NAME              | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | INDEX_LENGTH | CREATE_TIME | UPDATE_TIME |
+------------+--------------+------------+--------+-------------------+------------+----------------+-------------+--------------+-------------+-------------+
|   <span>28051622</span> | test         | tbl        | InnoDB | #sql8c3_1ac08a6_0 |       1265 |             51 |       65536 |            0 | NULL        | NULL        |
+------------+--------------+------------+--------+-------------------+------------+----------------+-------------+--------------+-------------+-------------+
</pre>
<p><em>SESSION_ID</em> is the same as the thread identifier in the process list, so you can connect any killed threads to their temporary tables.</p>
<p>The other type of temporary tables cannot be easily traced. Sometimes it&#8217;s possible to spot the information in the <em>SHOW PROCESSLIST</em> output:</p>
<pre>
mysql> show processlist;
+----------+------+-----------+------+---------+------+----------------------+---------------------------------------------------+
| Id       | User | Host      | db   | Command | Time | State                | Info                                              |
+----------+------+-----------+------+---------+------+----------------------+---------------------------------------------------+
| <span>1934</span>     | root | localhost | test | <span>Killed</span>  |    4 | Copying to tmp table | INSERT INTO test.tbl SELECT * FROM test.testtable |
..
</pre>
<p>Sometimes you can check what temporary files the instance keeps open:</p>
<pre>
server ~ # lsof -c mysqld | grep \#sql
mysqld  5626 mysql  138u   REG              253,1       1024 43843585  /vol/vol1/mysql/#sql_95fa_0.MYI
mysqld  5626 mysql  139u   REG              253,1  <span>227262885</span> 43843605  /vol/vol1/mysql/#sql_95fa_0.MYD
</pre>
<p>The colored value is the file&#8217;s size. These may help you to make an assumption that database could be removing a temporary table.</p>
<h6>Conclusions</h6>
<p>From time to time it may be normal to see a database thread that was killed, but didn&#8217;t die immediately, or a query that can&#8217;t seem to end. The real operation is not be performed synchronously with the kill command and afterwards MySQL <strong>may still need some time to clean things up</strong> properly. </p>
<p>No matter what the real cause is, it is <strong>impossible to get rid of</strong> such <em>hanging</em> threads without a database restart. They should, however, simply be allowed to go away on their own. </p>
<p>There is also <strong>no way of forcing a kill</strong> that would execute instantly like <em>kill -9 &lt;pid&gt;</em> in Unix systems.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33235&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33235&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 22:33:46 +0000</pubDate>
    <dc:creator>dba square</dc:creator>
    <category>Managing MySQL</category>
    <category>Admin</category>
    <category>MySQL</category>
    <category>Query</category>
    <category>Thread</category>
  </item>

  <item>
    <title>Under the Hood with Connector/J's &amp;quot;rewriteBatchStatements=true&amp;quot;</title>
    <guid isPermaLink="false">http://www.jroller.com/mmatthews/entry/under_the_hood_with_rewritebatchstatements</guid>
    <link>http://www.jroller.com/mmatthews/entry/under_the_hood_with_rewritebatchstatements</link>
    <description>My old post (http://www.jroller.com/mmatthews/entry/speeding_up_batch_inserts_for) on the performance gains from batch rewritten statements gets regurgitated in various forums, and conference sessions, and often people miss the nuances of it.

	Under the hood, what is happening with this feature is the following:

	(1) The driver attempts to detect that the SQL being prepared is an INSERT. We (on purpose) don&amp;#8216;t ship a full-fledged parser in the driver, so this works 95% of the time. For the other 5%, you&amp;#8216;re out of luck unless you can simplify your query text.
(2) If the statement is an INSERT, the driver attempts to determine if it can be rewritten as a multi-value INSERT. From the code itself, the conditions are:

	// Needs to be INSERT, can&amp;#8216;t have INSERT &amp;#8230; SELECT or
// INSERT &amp;#8230; ON DUPLICATE KEY UPDATE with an id=LAST_INSERT_ID(...)

	If not, the driver will determine whether it is more cost-effective round-trip-wise to enable multistatements on the connection, and send the batch as chunks of semicolon-separated statements. This means that any kind of batch DML can benefit from this feature, just that INSERTs benefit more because of the way MySQL handles multi-value INSERTs.
(3) The driver will send &amp;#8220;chunks&amp;#8221; that are as close to max_allowed_packet size in bytes as possible, until the batch has been completely sent.
(4) The driver does not re-order the batch
(5) You can use Statement.getGeneratedKeys() with this feature
(6) You can use set*Stream() with this feature
(6) You can use server-side prepared statements with this feature as well, and if the batch contains streams (CLOBs or BLOBs), they will be streamed to the server, using less memory.

	As you can see, this is almost a win-win feature to enable, especially if your application or ORM can do DML in batches (most do). The only reason it&amp;#8216;s not enabled by default is because of (1), maybe as this feature sees more use, we can feel safer enabling it by default.</description>
    <content:encoded><![CDATA[<p>My old post (<a href="http://www.jroller.com/mmatthews/entry/speeding_up_batch_inserts_for">http://www.jroller.com/mmatthews/entry/speeding_up_batch_inserts_for</a>) on the performance gains from batch rewritten statements gets regurgitated in various forums, and conference sessions, and often people miss the nuances of it.</p>

	<p>Under the hood, what is happening with this feature is the following:</p>

	<p>(1) The driver attempts to detect that the <span>SQL</span> being prepared is an <span>INSERT</span>. We (on purpose) don&#8216;t ship a full-fledged parser in the driver, so this works 95% of the time. For the other 5%, you&#8216;re out of luck unless you can simplify your query text.<br />
(2) If the statement is an <span>INSERT</span>, the driver attempts to determine if it can be rewritten as a multi-value <span>INSERT</span>. From the code itself, the conditions are:</p>

	<p>// Needs to be <span>INSERT</span>, can&#8216;t have <span>INSERT </span>&#8230; <span>SELECT</span> or<br />
// <span>INSERT </span>&#8230; <span>ON DUPLICATE KEY UPDATE</span> with an id=LAST_INSERT_ID(...)</p>

	<p>If not, the driver will determine whether it is more cost-effective round-trip-wise to enable multistatements on the connection, and send the batch as chunks of semicolon-separated statements. This means that <strong>any</strong> kind of batch <span>DML</span> can benefit from this feature, just that <span>INSER</span>Ts benefit more because of the way MySQL handles multi-value <span>INSER</span>Ts.<br />
(3) The driver will send &#8220;chunks&#8221; that are as close to max_allowed_packet size in bytes as possible, until the batch has been completely sent.<br />
(4) The driver does <strong>not</strong> re-order the batch<br />
(5) You <strong>can</strong> use Statement.getGeneratedKeys() with this feature<br />
(6) You <strong>can</strong> use set*Stream() with this feature<br />
(6) You <strong>can</strong> use server-side prepared statements with this feature as well, and if the batch contains streams (CLOBs or <span>BLO</span>Bs), they will be streamed to the server, using less memory.</p>

	<p>As you can see, this is almost a win-win feature to enable, especially if your application or <span>ORM</span> can do <span>DML</span> in batches (most do). The only reason it&#8216;s not enabled by default is because of (1), maybe as this feature sees more use, we can feel safer enabling it by default.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33234&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33234&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 22:21:34 +0000</pubDate>
    <dc:creator>Mark Matthews</dc:creator>
    <category>Java</category>
  </item>

  <item>
    <title>Speeding up EC2 work by using AWS tools and scripts to bypass the AWS management console</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-31421954.post-3485635415905853504</guid>
    <link>http://mysqldba.blogspot.com/2012/05/speeding-up-ec2-work-by-using-aws-tools.html</link>
    <description>Believe me managing EC2 instances is not as simple or magical as marketers would like for you to believe. The cloud gets complicated when it gets bigger.  EC2 really only enables a person to ignore power, network layout (which is bad), and getting more servers that end up costing more then actual servers fast.Things that EC2 is missing to make life easier for the developer:Ability to update all servers with packages and code. Natively they do not support the ability to push files or install new software packages to server groups. Thus install cluster-it and puppet and write your own deploy program.Server names and the EC2 AWS management console do not match. Everything is referenced by instance ids. The interface does not allow one to launch many instances in a named pattern so you have to go back and sync up the instance with the internal named used in the app. Syncing up the names is very tedious and time consuming process through the console.Assigning EBS volumes is a pain in the ass as well. Essentially you need to assign them one by one, where each add takes more then 2 mins todo this is not good time spent. For instance it took me roughly 20 mins to attach 8 63GB EBS volumes to a single server.Amazon is perfectly aware of these limitations-and do not hide from it. They are going after something bigger. They are providing a platform. There is an API for everything you need to make your work easier. Now the pain is to learn the API and use it in your favor. There are companies that built a business on making a better interface for the AWS console but getting it done yourself is cheaper.My personal mantra is to automate things that I have to do more then once. Anytime that I deploy new instances, I take the private IP add it to DNS, make an API call through ec2-describe-instances, find the instance id and update the name through ec2-create-tags. This solves the problem that I have with mapping instance ids to my internal name which the app uses. For instance: #!/usr/bin/perl -w ##use strict;use Data::Dumper;open(HOSTS, &quot;&amp;lt;/etc/hosts&quot;) or die($!);my $hosts = {};while(&amp;lt;HOSTS&amp;gt;){    my ($ip, $hostname, undef) = split(/\s+/, $_);    $hosts-&amp;gt;{$ip} = $hostname;}  open(FH, &quot;/opt/aws/bin/ec2-describe-instances -C cert.pem -K x509.pem --region us-west-1|&quot;) or die($!);while(&amp;lt;fh&amp;gt;){    if ($_ =~ /^INSTANCE\t(.*)/){        my (@fields) = split(/\s+/, $1);        # 0 - instance        # 1 - ami        # 2 - public dns        # 3 - private dns        # 4 - state        # 5 - ??        # 6 - ??        # 7 - instance type        # 8 - date created        # 9 - DC        # 10 - ??        # 11 - monitoring state        # 12 - public ip        # 13 - private ip        # 14 - ebs        # 15 - ??      if ($fields[4] eq 'running'){            my $role;            my $hostname = $hosts-&amp;gt;{$fields[13]};                         if (!$hostname) {                print &quot;$fields[13] is not in the hosts file skipping..\n&quot;;                next;            }            if ($hostname =~ /^job/){                $role = 'gearman-worker';            }            if ($hostname =~ /^gearman/){                $role = 'gearman-queue';            }            if ($hostname =~ /^www/){                $role = 'webserver';            }            if ($hostname =~ /^memc/){                $role = 'memcache';            }            if ($hostname =~ /^db/){                $role = 'database';            }            if ($hostname =~ /^dbshard/) {                $role = 'database-shard';            }            if (!$role){                print &quot;$hostname does not have a role\n&quot;;                $role = 'other';            }            system(&quot;./aws/bin/ec2-create-tags -C cert.pem -K x509.pem --region us-west-1 &quot;.$fields[0] .&quot; --tag Name=$hostname --tag Role=$role&quot;);        }    }}Now to attach disks to an instance, that I am upgrading or re-purposing I wrote a quick script that describes the input instance after translating from my internal name to instance id. Calculates the size of each disk and attaches said disks. For instance:  #!/usr/bin/perl -w##use strict;use Data::Dumper;use POSIX qw(ceil); print &quot;Enter Hostname: &quot;;my $hostname = &amp;lt;&amp;gt;;chomp($hostname);my $cmd = './aws/bin/ec2-describe-instances -C cert.pem -K x509.pem --region us-west-1 --filter=&quot;tag-key=Name&quot; --filter=&quot;tag-value=' . $hostname . '&quot;'; open(FH, &quot;$cmd|&quot;) or die (&quot;Awesome death: $!\n&quot;); my $instance = &quot;&quot;;my $lastDisk = &quot;&quot;;my $diskCount = &quot;&quot;;while(&amp;lt;FH&amp;gt;){  if($_ =~ /^INSTANCE\t(.*)/){        my (@fields) = split(/\s+/, $1);        $instance = $fields[0];        print &quot;Instance=$instance\n&quot;;    }      if($_ =~ /^BLOCKDEVICE\t(.*)/){        my (@fields) = split(/\s+/, $1);        $diskCount++;        $lastDisk = $fields[0];        print &quot;$lastDisk\n&quot;;    }} print &quot;How many disks you would like to add: &quot;;my $totalAddDisks = &amp;lt;&amp;gt;;chomp($totalAddDisks); print &quot;You picked $totalAddDisks\n&quot;;print &quot;What is the total size of the Raid0 Array in GB: &quot;;my $totalSize = &amp;lt;&amp;gt;;chomp($totalSize); print &quot;You picked $totalSize GB\n&quot;;my $sizeperdisk = ceil($totalSize/$totalAddDisks);print &quot;The size per disk: $sizeperdisk\n&quot;; $lastDisk =~ /sd(\S)/;my $lastDeviceLetter = $1;my @devicesavail = ($lastDeviceLetter .. 'z'); for(my $i = 1; $i &amp;lt;= $totalAddDisks; $i++){    $cmd = &quot;./aws/bin/ec2-create-volume --size $sizeperdisk --region us-west-1 --availability-zone us-west-1c -C cert.pem  -K x509.pem&quot;;      my $ret = `$cmd`;    my (@output) = split(/\s+/, $ret);        $cmd = &quot;./aws/bin/ec2-attach-volume --region us-west-1 -C cert.pem -K x509.pem $output[1] --instance $instance --device /dev/sd$devicesavail[$i]&quot;;    $ret = `$cmd`;        if ($ret =~ /attaching/){        print &quot;All good do the next one\n&quot;;    } else {        die(&quot;Did not work\n&quot;);    }}These are rough and dirty scripts that get the job done for my environment. The end goal when given time is to turn these scripts into a package talking over httpd that makes life easier when working in EC2. Using these two script have reduced the management time from 1 hour per server upgrade to a few minutes.</description>
    <content:encoded><![CDATA[Believe me managing EC2 instances is not as simple or magical as marketers would like for you to believe. The cloud gets complicated when it gets bigger.  EC2 really only enables a person to ignore power, network layout (which is bad), and getting more servers that end up costing more then actual servers fast.<br /><br />Things that EC2 is missing to make life easier for the developer:<br /><br />Ability to update all servers with packages and code. Natively they do not support the ability to push files or install new software packages to server groups. Thus install cluster-it and <a href="http://puppetlabs.com/puppet/puppet-open-source/" target="_blank">puppet</a> and write your own deploy program.<br /><br />Server names and the EC2 AWS management console do not match. Everything is referenced by instance ids. The interface does not allow one to launch many instances in a named pattern so you have to go back and sync up the instance with the internal named used in the app. Syncing up the names is very tedious and time consuming process through the console.<br /><br />Assigning EBS volumes is a pain in the ass as well. Essentially you need to assign them one by one, where each add takes more then 2 mins todo this is not good time spent. For instance it took me roughly 20 mins to attach 8 63GB EBS volumes to a single server.<br /><br />Amazon is perfectly aware of these limitations-and do not hide from it. They are going after something bigger. They are providing a platform. There is an API for everything you need to make your work easier. Now the pain is to learn the API and use it in your favor. There are companies that built a business on making a better interface for the AWS console but getting it done yourself is cheaper.<br /><br />My personal mantra is to automate things that I have to do more then once. Anytime that I deploy new instances, I take the private IP add it to DNS, make an API call through ec2-describe-instances, find the instance id and update the name through ec2-create-tags. This solves the problem that I have with mapping instance ids to my internal name which the app uses. For instance:<br /><pre> <br />#!/usr/bin/perl -w <br />#<br />#<br />use strict;<br />use Data::Dumper;<br />open(HOSTS, "&lt;/etc/hosts") or die($!);<br /><br />my $hosts = {};<br />while(&lt;HOSTS&gt;){<br />    my ($ip, $hostname, undef) = split(/\s+/, $_);<br />    $hosts-&gt;{$ip} = $hostname;<br />}<br /><br /> <br /> <br />open(FH, "/opt/aws/bin/ec2-describe-instances -C cert.pem -K x509.pem --region us-west-1|") or die($!);<br />while(&lt;fh&gt;){<br />    if ($_ =~ /^INSTANCE\t(.*)/){<br />        my (@fields) = split(/\s+/, $1);<br />        # 0 - instance<br />        # 1 - ami<br />        # 2 - public dns<br />        # 3 - private dns<br />        # 4 - state<br />        # 5 - ??<br />        # 6 - ??<br />        # 7 - instance type<br />        # 8 - date created<br />        # 9 - DC<br />        # 10 - ??<br />        # 11 - monitoring state<br />        # 12 - public ip<br />        # 13 - private ip<br />        # 14 - ebs<br />        # 15 - ??<br /> <br />     if ($fields[4] eq 'running'){<br />            my $role;<br />            my $hostname = $hosts-&gt;{$fields[13]};<br />             <br />            if (!$hostname) {<br />                print "$fields[13] is not in the hosts file skipping..\n";<br />                next;<br />            }<br />            if ($hostname =~ /^job/){<br />                $role = 'gearman-worker';<br />            }<br />            if ($hostname =~ /^gearman/){<br />                $role = 'gearman-queue';<br />            }<br />            if ($hostname =~ /^www/){<br />                $role = 'webserver';<br />            }<br />            if ($hostname =~ /^memc/){<br />                $role = 'memcache';<br />            }<br />            if ($hostname =~ /^db/){<br />                $role = 'database';<br />            }<br />            if ($hostname =~ /^dbshard/) {<br />                $role = 'database-shard';<br />            }<br />            if (!$role){<br />                print "$hostname does not have a role\n";<br />                $role = 'other';<br />            }<br />            system("./aws/bin/ec2-create-tags -C cert.pem -K x509.pem --region us-west-1 ".$fields[0] ." --tag Na<br />me=$hostname --tag Role=$role");<br />        }<br />    }<br />}<br /></pre><br />Now to attach disks to an instance, that I am upgrading or re-purposing I wrote a quick script that describes the input instance after translating from my internal name to instance id. Calculates the size of each disk and attaches said disks. For instance: <br /><pre> <br />#!/usr/bin/perl -w<br />#<br />#<br />use strict;<br />use Data::Dumper;<br />use POSIX qw(ceil);<br /> <br />print "Enter Hostname: ";<br />my $hostname = &lt;&gt;;<br />chomp($hostname);<br />my $cmd = './aws/bin/ec2-describe-instances -C cert.pem -K x509.pem --region us-west-1 --filter="tag-key=Name" --<br />filter="tag-value=' . $hostname . '"';<br /> <br />open(FH, "$cmd|") or die ("Awesome death: $!\n");<br /> <br />my $instance = "";<br />my $lastDisk = "";<br />my $diskCount = "";<br />while(&lt;FH&gt;){<br /> <br /> <br />if($_ =~ /^INSTANCE\t(.*)/){<br />        my (@fields) = split(/\s+/, $1);<br />        $instance = $fields[0];<br />        print "Instance=$instance\n";<br />    }<br />  <br />    if($_ =~ /^BLOCKDEVICE\t(.*)/){<br />        my (@fields) = split(/\s+/, $1);<br />        $diskCount++;<br />        $lastDisk = $fields[0];<br />        print "$lastDisk\n";<br />    }<br />}<br /> <br />print "How many disks you would like to add: ";<br />my $totalAddDisks = &lt;&gt;;<br />chomp($totalAddDisks);<br /> <br />print "You picked $totalAddDisks\n";<br />print "What is the total size of the Raid0 Array in GB: ";<br />my $totalSize = &lt;&gt;;<br />chomp($totalSize);<br /> <br />print "You picked $totalSize GB\n";<br />my $sizeperdisk = ceil($totalSize/$totalAddDisks);<br />print "The size per disk: $sizeperdisk\n";<br /> <br />$lastDisk =~ /sd(\S)/;<br />my $lastDeviceLetter = $1;<br />my @devicesavail = ($lastDeviceLetter .. 'z');<br /> <br />for(my $i = 1; $i &lt;= $totalAddDisks; $i++){<br />    $cmd = "./aws/bin/ec2-create-volume --size $sizeperdisk --region us-west-1 --availability-zone us-west-1c -C cert.pem  -K<br /> x509.pem";<br />  <br />    my $ret = `$cmd`;<br />    my (@output) = split(/\s+/, $ret);<br />    <br />    $cmd = "./aws/bin/ec2-attach-volume --region us-west-1 -C cert.pem -K x509.pem $output[1] --instance $instanc<br />e --device /dev/sd$devicesavail[$i]";<br />    $ret = `$cmd`;<br />    <br />    if ($ret =~ /attaching/){<br />        print "All good do the next one\n";<br />    } else {<br />        die("Did not work\n");<br />    }<br />}<br /></pre><br />These are rough and dirty scripts that get the job done for my environment. The end goal when given time is to turn these scripts into a package talking over httpd that makes life easier when working in EC2. Using these two script have reduced the management time from 1 hour per server upgrade to a few minutes.<div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/31421954-3485635415905853504?l=mysqldba.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33231&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33231&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 20:58:00 +0000</pubDate>
    <dc:creator>Dathan Pattishall</dc:creator>
  </item>

  <item>
    <title>WordPress on S3: the beauty of simplicity</title>
    <guid isPermaLink="false">http://www.oblaksoft.com/?p=2524</guid>
    <link>http://www.oblaksoft.com/wordpress-on-s3-the-beauty-of-simplicity/</link>
    <description>My first computer program was written almost quarter a century ago on a BK-0010 computer.  It was very simple: the program asked the user to enter their name and then greeted the user using the entered name, like “Hello, Artem!”.  I was fascinated.  A couple of lines written in Vilnius BASIC transformed a piece of metal and silicon into a considerate thing that cared about a person’s name enough to remember it :-).  Of course, the first experience doesn’t represent the day-to-day routine of software development, but the moments when I see a couple of lines making an amazing transformation still enchant me, and remind me why I’ve been writing code all this time.
I’ve just experienced this very same first-time feeling as we’ve released Yapixx – a picture sharing web application using the cloud storage.   The most amazing thing about Yapixx is that we wrote very little code to make it happen: most of its functionality is provided by WordPress, which by the way we didn’t modify at all.  
On one hand Yapixx is just WordPress, enhanced with plugins and configured to provide good picture sharing experience.  
On the other hand, Yapixx has gone where WordPress could not go before – Yapixx runs completely on top of Amazon S3, using the enormous power of S3 to make serving the users’ pictures highly scalable and storing all data extremely durable. 

As an engineer I’ve been on the never ending quest of finding new ways to do more with less.  How do I write less code and provide more functional solution?  How do I empower my customers to accomplish more with applying very little effort (or preferably no effort at all)?  Yapixx is one of those gems – it shows how unbelievably simple it is to run a beautiful website on top of Amazon S3: you don’t need to learn new APIs, you don’t have to know how to write code, you don’t even have to know that you are relying on MySQL + ClouSE to store data reliably and securely in the cloud!
Yapixx is not a toy application: it&amp;#8217;s a fully functional ready-to-run WordPress on Amazon S3.  With a few clicks Yapixx can be transformed into anything WordPress can do, while storing all website content in Amazon S3.  Just continue doing what you set to do with your Web site – to build a beautifully powerful representation of you, your company, and your cause.
Amazon S3 is a very powerful service designed for building one-of-a-kind massively distributed applications.  This is its strength but it’s also its weakness: if you are not building one-of-a-kind massively distributed application, the low-level vendor-specific APIs and eventual consistency guarantees are just the unnecessary complexities that you pay for, but don’t use.  WordPress is an example of how to make Amazon S3 a true cloud storage utility service that can be easily used by millions.  It’s a people-oriented (as opposed to technology-oriented) approach to building a distributed system – as a constellation of beautiful websites powered by creativity and uniqueness of individuals, like the Internet itself is!
‘Nuff said :-).  Get your own WordPress on S3 for free now.
Artem</description>
    <content:encoded><![CDATA[<p>My first computer program was written almost quarter a century ago on a <a href="http://upload.wikimedia.org/wikipedia/commons/8/89/Bk0010-01-sideview.jpg">BK-0010</a> computer.  It was very simple: the program asked the user to enter their name and then greeted the user using the entered name, like “Hello, Artem!”.  I was fascinated.  A couple of lines written in Vilnius BASIC transformed a piece of metal and silicon into a considerate thing that cared about a person’s name enough to remember it :-).  Of course, the first experience doesn’t represent the day-to-day routine of software development, but the moments when I see a couple of lines making an amazing transformation still enchant me, and remind me why I’ve been writing code all this time.</p>
<p>I’ve just experienced this very same first-time feeling as we’ve released <a href="http://www.oblaksoft.com/wordpress-s3-newsletter-may-2012">Yapixx</a> – a picture sharing web application using the cloud storage.   The most amazing thing about Yapixx is that we wrote very little code to make it happen: most of its functionality is provided by <a href="http://wordpress.org/">WordPress</a>, which by the way we didn’t modify at all.  </p>
<p>On one hand Yapixx is just WordPress, enhanced with plugins and configured to provide good picture sharing experience.  </p>
<p>On the other hand, Yapixx has gone where WordPress could <strong>not </strong>go before – Yapixx runs completely on top of <a href="http://aws.amazon.com/s3">Amazon S3</a>, using the enormous power of S3 to make serving the users’ pictures highly scalable and storing all data extremely durable. <br />
<span></span></p>
<p>As an engineer I’ve been on the never ending quest of finding new ways to do more with less.  How do I write less code and provide more functional solution?  How do I empower my customers to accomplish more with applying very little effort (or preferably no effort at all)?  Yapixx is one of those gems – it shows how unbelievably simple it is to run a beautiful website on top of Amazon S3: you don’t need to learn new APIs, you don’t have to know how to write code, you don’t even have to know that you are relying on MySQL + ClouSE to store data reliably and securely in the cloud!</p>
<p>Yapixx is not a toy application: it&#8217;s a fully functional ready-to-run WordPress on Amazon S3.  With a few clicks Yapixx can be transformed into anything WordPress can do, while storing all website content in Amazon S3.  Just continue doing what you set to do with <em>your</em> Web site – to build a beautifully powerful representation of you, your company, and your cause.</p>
<p>Amazon S3 is a very powerful service designed for building one-of-a-kind massively distributed applications.  This is its strength but it’s also its weakness: if you are <strong>not</strong> building one-of-a-kind massively distributed application, the low-level vendor-specific APIs and eventual consistency guarantees are just the unnecessary complexities that you pay for, but don’t use.  WordPress is an example of how to make Amazon S3 a true cloud storage utility service that can be easily used by millions.  It’s a people-oriented (as opposed to technology-oriented) approach to building a distributed system – as a constellation of beautiful websites powered by creativity and uniqueness of individuals, like the Internet itself is!</p>
<p>‘Nuff said :-).  Get your own <a href="http://www.oblaksoft.com/downloads">WordPress on S3</a> for free now.</p>
<p>Artem</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33229&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33229&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 19:00:46 +0000</pubDate>
    <dc:creator>Artem Livshits</dc:creator>
    <category>Founders BLOG</category>
    <category>Amazon</category>
    <category>cloud</category>
    <category>MySQL</category>
    <category>S3</category>
    <category>website</category>
    <category>Wordpress</category>
    <category>YAPIXX</category>
  </item>

  <item>
    <title>Announcement of Percona XtraDB Cluster 5.5.23</title>
    <guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=9479</guid>
    <link>http://www.mysqlperformanceblog.com/2012/05/14/announcement-of-percona-xtradb-cluster-5-5-23/</link>
    <description>Our previous GA release of Percona XtraDB Cluster caused a lot of interest and feedback. I am happy to announce next version Percona XtraDB Cluster 5.5.23, which comes with bug fixes and improvements.
List of changes:

Fixes merged from upstream (Codership-mysql)
Support for MyISAM, now changes to MyISAM tables are replicated to other nodes
Improvements to XtraBackup SST methods, better error handling
New SST wsrep_sst_method=skip, useful when you start all nodes from the same sources (i.e. backup)
Ability to pass list of IP addresses for a new node, it will connect to the first available

Binaries are available from downloads area or from our repositories.
For this release we will provides binaries for Ubuntu 12.04, they are coming soon.
If you want to know more how to migrate to XtraDB Cluster, we will be giving a free webinar on June 6th.
This is an General Availability release.  We did our best to eliminate bugs and problems during alpha and beta testing release, but this is a software, so bugs are expected. If you encounter them, please report to our bug tracking system.
Links:


We provide tar.gz and RPM binaries for RedHat (CentOS, Oracle Linux) 5 and 6, and Debian packages.
Downloads: http://www.percona.com/downloads/Percona-XtraDB-Cluster/


Documentation
Codership Wiki


General Discussion group
Launchpad project
Bug reports
</description>
    <content:encoded><![CDATA[<p>Our previous GA release of Percona XtraDB Cluster caused a lot of interest and feedback. I am happy to announce next version <a href="http://www.percona.com/software/percona-xtradb-cluster/">Percona XtraDB Cluster</a> 5.5.23, which comes with bug fixes and improvements.</p>
<p>List of changes:</p>
<ul>
<li><a href="http://www.codership.com/content/wsrep-patch-235-mysql-5523-released">Fixes merged</a> from upstream (Codership-mysql)</li>
<li>Support for MyISAM, now changes to MyISAM tables are replicated to other nodes</li>
<li>Improvements to XtraBackup SST methods, better error handling</li>
<li>New SST wsrep_sst_method=skip, useful when you start all nodes from the same sources (i.e. backup)</li>
<li>Ability to pass list of IP addresses for a new node, it will connect to the first available</li>
</ul>
<p>Binaries are available from downloads area or from our repositories.</p>
<p>For this release we will provides binaries for Ubuntu 12.04, they are coming soon.</p>
<p>If you want to know more how to migrate to XtraDB Cluster, we will be giving <a href="http://www.percona.com/webinars/2012-06-06-migrating-to-percona-xtradb-cluster/">a free webinar on June 6th</a>.</p>
<p>This is an General Availability release.  We did our best to eliminate bugs and problems during alpha and beta testing release, but this is a software, so bugs are expected. If you encounter them, please report to <a href="https://bugs.launchpad.net/percona-xtradb-cluster">our bug tracking system</a>.</p>
<p>Links:</p>
<ul>
<li>
We provide tar.gz and RPM binaries for RedHat (CentOS, Oracle Linux) 5 and 6, and Debian packages.<br />
Downloads: <a href="http://www.percona.com/downloads/Percona-XtraDB-Cluster/">http://www.percona.com/downloads/Percona-XtraDB-Cluster/</a>
</li>
<li>
<a href="http://www.percona.com/doc/percona-xtradb-cluster/index.html">Documentation</a><br />
<a href="http://www.codership.com/wiki/doku.php">Codership Wiki</a>
</li>
<li>
<a title="http://groups.google.com/group/percona-discussion" href="http://groups.google.com/group/percona-discussion">General Discussion group</a></li>
<li><a href="https://launchpad.net/percona-xtradb-cluster">Launchpad project</a></li>
<li><a href="https://bugs.launchpad.net/percona-xtradb-cluster">Bug reports</a></li>
</ul><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33228&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33228&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 17:33:00 +0000</pubDate>
    <dc:creator>MySQL Performance Blog</dc:creator>
    <category>MySQL</category>
    <category>Percona Software</category>
    <category>XtraDB Cluster</category>
  </item>

  <item>
    <title>Tokutek Welcomes Gerry Narvaja!</title>
    <guid isPermaLink="false">http://www.tokutek.com/?p=4112</guid>
    <link>http://www.tokutek.com/2012/05/tokutek-welcomes-gerry-narvaja/</link>
    <description>We are excited to have Gerry Narvaja start today at Tokutek! Gerry has spent more than 25 years in the software industry, most of them working with databases for different kinds of applications, from embedded to large-scale web products. Gerry worked first at MySQL, and then Sun Microsystems supporting the Sales teams. In 2008 he transitioned into being a Senior MySQL DBA. Gerry graduated as an Electronic Engineer from I.T.B.A (Instituto Tecnológico de Buenos Aires) and has an M.B.A. from Universidad del Salvador in collaboration with S.U.N.Y.A (State University of NY at Albany).
Gerry enjoys helping users to solve complex database production issues. For almost a year he has been co-hosting the popular MySQL Community podcast, OurSQL, which was given the MySQL Community Contributor of the Year 2012 award at the recent Percona MySQL Users Conference. Gerry and Martín Farach-Colton, our CTO, will also be speaking next month at the first ever Latin American MySQL / MariaDB Conference in Argentina.
Please feel free to drop Gerry a line at gerry@tokutek.com with your toughest MySQL and MariaDB issues!</description>
    <content:encoded><![CDATA[<p>We are excited to have <a href="https://twitter.com/#!/seattlegaucho" target="_blank">Gerry Narvaja</a> start today at Tokutek! Gerry has spent more than 25 years in the software industry, most of them working with databases for different kinds of applications, from embedded to large-scale web products. Gerry worked first at MySQL, and then Sun Microsystems supporting the Sales teams. In 2008 he transitioned into being a Senior MySQL DBA. Gerry graduated as an Electronic Engineer from I.T.B.A (Instituto Tecnológico de Buenos Aires) and has an M.B.A. from Universidad del Salvador in collaboration with S.U.N.Y.A (State University of NY at Albany).</p>
<p>Gerry enjoys helping users to solve complex database production issues. For almost a year he has been co-hosting the popular MySQL Community podcast, <a href="http://www.oursql.com/" target="_blank">OurSQL</a>, which was given the <a href="http://openlife.cc/blogs/2012/april/mysql-community-awards-2012-and-winners-are" target="_blank">MySQL Community Contributor of the Year 2012 award</a> at the recent Percona MySQL Users Conference. Gerry and Martín Farach-Colton, our CTO, will also be speaking next month at the first ever <a href="http://mariadbnosqlcloud.com/" target="_blank">Latin American MySQL / MariaDB Conference</a> in Argentina.</p>
<p>Please feel free to drop Gerry a line at <a href="mailto:gerry@tokutek.com">gerry@tokutek.com</a> with your toughest MySQL and MariaDB issues!</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33219&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33219&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 13:09:00 +0000</pubDate>
    <dc:creator>Tokuview Blog</dc:creator>
    <category>TokuView</category>
    <category>Announcement</category>
    <category>mysql</category>
    <category>NewSQL</category>
    <category>percona</category>
    <category>storage engine</category>
    <category>TokuDB</category>
    <category>Tokutek</category>
  </item>

  <item>
    <title>Hopper for InterBase, 1.0 released</title>
    <guid isPermaLink="false">2453B7B7-13DE-4BB2-ABFA-A9B301E42FE9</guid>
    <link>http://www.upscene.com/displaynews.php?item=20120514</link>
    <description>Hopper for InterBase, 1.0 released 
[2012-05-09]

Upscene Productions is proud to announce the first release of our new product &quot;Hopper&quot;, a Stored Code Debugger for InterBase.

Thanks to the feedback of people who downloaded the betas, we were able to improve Hopper.

Hopper is currently available for InterBase and Firebird, the MySQL Edition will follow shortly.

More information available at the Hopper page, download your copy today via our downloads page, pricing information is available.</description>
    <content:encoded><![CDATA[<b>Hopper for InterBase, 1.0 released </b><br />
[2012-05-09]<br />
<br />
Upscene Productions is proud to announce the first release of our new product "Hopper", a Stored Code Debugger for InterBase.<br />
<br />
Thanks to the feedback of people who downloaded the betas, we were able to improve Hopper.<br />
<br />
Hopper is currently available for InterBase and Firebird, the MySQL Edition will follow shortly.<br />
<br />
More information available at the <a href="http://www.upscene.com/go/?go=hopper" target="_blank">Hopper page</a>, download your copy today via our <a href="http://www.upscene.com/go/?go=download" target="_blank">downloads page</a>, <a href="http://www.upscene.com/go/?go=purchase" target="_blank">pricing information</a> is available.<br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33218&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33218&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 12:44:03 +0000</pubDate>
    <dc:creator>Martijn Tonies</dc:creator>
  </item>

  <item>
    <title>Challenges in reaching 1BN reads and updates per minute for MySQL Cluster 7.2</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-14455177.post-2185551902926855242</guid>
    <link>http://mikaelronstrom.blogspot.com/2012/05/challenges-in-reaching-1bn-reads-and.html</link>
    <description>In an earlier blog we've described the general high-level idea of how to achieve 10X better performance for MySQL Cluster 7.2 compared to MySQL Cluster 7.1.Naturally the development is never as straightforward as the high-level view looks like. In this blog I'll mention a few of the most important roadblocks on the path to improved performance of MySQL Cluster 7.2 that we met and resolved.Initially when we increased the number of LQH threads from 4 to 16 we only saw scaling to 8 LQH threads and we saw no scaling in going to 16 LQH threads. This was very puzzling since we don't really have any mutexes that should be an issue. However we looked into the mutexes that we had and managed to decrease the number of conflicts on the send mutexes by a factor of 15. This did however not improve performance at all.Next we noted using oprofile that there was a few functions that for some reason 50% of the CPU time was spent. This was quite surprising and given that the exactness of those measurements is not always 100%, I was&amp;nbsp; very suspicious about those numbers. Eventually however the reason dawned on me.The reason was that I had some cache lines that was too often updated. This lead to that some instructions took several microseconds to execute since all threads were serialised on updating this cacheline.The first such instance was a piece of code used to check whether send buffers were overloaded. In case the send buffer is more than 75% overloaded we start rejecting client requests to ensure that already ongoing requests are able to complete. This is accomplished using a bitmap with one bit per node we're communicating with. This bitmap is obviously global and this was updated every time we made a remote send to another node. This was obviously quite unnecessary to update it every time, it's enough to update when the state changes, so a simple if-statement resolved that problem.The next problem was even harder to understand how it could be an issue. It turned out that the problem resided in our crash information subsystem. We have a macro called jam() (Jump Address Memory, an acronym we inherited from the AXE system once upon a time). This macro inserts the line number we're currently executing together with sometimes the block number we're executing. When there was only one thread in the MySQL Cluster data nodes then this data structure was global and shared by all others.With the move to multithreaded architecture we changed this to be a data structure per thread such that we can get detailed information on each thread what it did before any crash.Most blocks are only executing in one thread and was fairly straightforward to change this. However in one case we have a code path which is used by all TC threads to ask the distribution handlers which nodes and threads that contain the data for a certain partition of the MySQL Cluster. The distribution handler thus is one block called from many threads and thus we needed to use different jam's dependent on which thread that called this function. When this wasn't done then this code showed up as another bottleneck since many threads tried to update the same cachelines again.With those fixes we were able to reach very good numbers on a single node with up to 16 LQH threads. However we saw that the risk of getting out of send buffer memory had severely increased due to the great increase of threads in the data node. The threads communicate using a lock-free scheme, however this means that there needs to be dedicated memory available for each two threads that communicate. Also the code doesn't always use the send buffer memory in the most efficient manner to speed up communication. This meant that we needed to do something about send buffer memory handling in order to make the data nodes as stable as before. We found three points in the code where we needed to pack send buffer memory, non of these were part of the normal code path but were vital to ensure that we packed things in cases when we got close to run out of send buffer memory. We also went through all send buffer memory configuration defaults and parameters and made them more appropriate to also handle larger data node configurations.As a final step towards getting single node performance working really good we also made sure that all data structures that were global were properly aligned on cacheline sizes.Putting the code to the test in a distributed environment also revealed a few new points to handle. At first we discovered that the free list of connections to the data node in an API had an interesting impact on the balance of the use of TC threads. For some reason, still unclear exactly how, a LIFO queue here had the impact that we used some TC threads up to 10x more than other TC threads which obviously made for very bad scalability with many TC threads. The solution was simple however, a quick change to a FIFO queue and the problem was no longer there.The next problem was yet one more imbalance, this time the imbalance was on LQH threads. The imbalance only showed up on very large clusters. This time the imbalance came from the manner in which we distribute rows into partitions. In order to make on-line reorganisation of tables very efficient we divide the table into a number of virtual partitions using a hashmap, then the virtual partitions are mapped to a real partition. Previously the hashmap always created 240 virtual partitions which was quite sufficient with 4 LQH threads, but not when moving to 16 LQH threads. So we changed to using 3840 virtual partitions instead.Actually the choice of 240 and 3840 is intricate here. 3840 is equal to 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 3 * 5. This means that if using 12 LQH threads (2 * 2 * 3) then the number of nodes in the cluster should either be on the form 2**n or 5 * 2**n. If not things will still work fine, but load will be slightly unbalanced since the real partitions will contain different numbers of virtual partitions. Uisng 16 LQH partitions the numbers of nodes should be on either of the forms 2**n, 3*2**n, 5*2**n or 3*5*2**n where n is less than or equal to 4. Thus we get from this calculation that 30 nodes is better than 32 nodes if using 16 LQH threads since it brings about a more even distribution of rows in the cluster.With these changes the performance of reads in a distributed environment was quite good and was providing very good scalability. However updates still caused issues.The problem for updates was that the receiver thread handling signals between the nodes in the same node group was overloaded. There was simply too many signals to handle. Much of this was due to some work that was left as a TODO after the 7.0 release since it wasn't an issue in 7.0, but now with the higher throughput it has become an issue.So the solution was to properly implement packing of signals such that several commit messages were packed together and similarly for the commit acknowledge from the API. These straightforward changes decreased the load on the receiver thread to a third and made it possible to push through 1.5M updates per second per node group. It is still possible that this becomes a bottleneck but it should be extremely unusual for a real-world application to reach this state.With all these changes implemented we managed to scale update and read performance linearly up to 30 nodes.</description>
    <content:encoded><![CDATA[<div dir="ltr" trbidi="on">In an earlier blog we've described the general high-level idea of how to achieve 10X better performance for MySQL Cluster 7.2 compared to MySQL Cluster 7.1.<br /><br />Naturally the development is never as straightforward as the high-level view looks like. In this blog I'll mention a few of the most important roadblocks on the path to improved performance of MySQL Cluster 7.2 that we met and resolved.<br /><br />Initially when we increased the number of LQH threads from 4 to 16 we only saw scaling to 8 LQH threads and we saw no scaling in going to 16 LQH threads. This was very puzzling since we don't really have any mutexes that should be an issue. However we looked into the mutexes that we had and managed to decrease the number of conflicts on the send mutexes by a factor of 15. This did however not improve performance at all.<br /><br />Next we noted using oprofile that there was a few functions that for some reason 50% of the CPU time was spent. This was quite surprising and given that the exactness of those measurements is not always 100%, I was&nbsp; very suspicious about those numbers. Eventually however the reason dawned on me.<br /><br />The reason was that I had some cache lines that was too often updated. This lead to that some instructions took several microseconds to execute since all threads were serialised on updating this cacheline.<br /><br />The first such instance was a piece of code used to check whether send buffers were overloaded. In case the send buffer is more than 75% overloaded we start rejecting client requests to ensure that already ongoing requests are able to complete. This is accomplished using a bitmap with one bit per node we're communicating with. This bitmap is obviously global and this was updated every time we made a remote send to another node. This was obviously quite unnecessary to update it every time, it's enough to update when the state changes, so a simple if-statement resolved that problem.<br /><br />The next problem was even harder to understand how it could be an issue. It turned out that the problem resided in our crash information subsystem. We have a macro called jam() (Jump Address Memory, an acronym we inherited from the AXE system once upon a time). This macro inserts the line number we're currently executing together with sometimes the block number we're executing. When there was only one thread in the MySQL Cluster data nodes then this data structure was global and shared by all others.<br /><br />With the move to multithreaded architecture we changed this to be a data structure per thread such that we can get detailed information on each thread what it did before any crash.<br /><br />Most blocks are only executing in one thread and was fairly straightforward to change this. However in one case we have a code path which is used by all TC threads to ask the distribution handlers which nodes and threads that contain the data for a certain partition of the MySQL Cluster. The distribution handler thus is one block called from many threads and thus we needed to use different jam's dependent on which thread that called this function. When this wasn't done then this code showed up as another bottleneck since many threads tried to update the same cachelines again.<br /><br />With those fixes we were able to reach very good numbers on a single node with up to 16 LQH threads. However we saw that the risk of getting out of send buffer memory had severely increased due to the great increase of threads in the data node. The threads communicate using a lock-free scheme, however this means that there needs to be dedicated memory available for each two threads that communicate. Also the code doesn't always use the send buffer memory in the most efficient manner to speed up communication. This meant that we needed to do something about send buffer memory handling in order to make the data nodes as stable as before. We found three points in the code where we needed to pack send buffer memory, non of these were part of the normal code path but were vital to ensure that we packed things in cases when we got close to run out of send buffer memory. We also went through all send buffer memory configuration defaults and parameters and made them more appropriate to also handle larger data node configurations.<br /><br />As a final step towards getting single node performance working really good we also made sure that all data structures that were global were properly aligned on cacheline sizes.<br /><br />Putting the code to the test in a distributed environment also revealed a few new points to handle. At first we discovered that the free list of connections to the data node in an API had an interesting impact on the balance of the use of TC threads. For some reason, still unclear exactly how, a LIFO queue here had the impact that we used some TC threads up to 10x more than other TC threads which obviously made for very bad scalability with many TC threads. The solution was simple however, a quick change to a FIFO queue and the problem was no longer there.<br /><br />The next problem was yet one more imbalance, this time the imbalance was on LQH threads. The imbalance only showed up on very large clusters. This time the imbalance came from the manner in which we distribute rows into partitions. In order to make on-line reorganisation of tables very efficient we divide the table into a number of virtual partitions using a hashmap, then the virtual partitions are mapped to a real partition. Previously the hashmap always created 240 virtual partitions which was quite sufficient with 4 LQH threads, but not when moving to 16 LQH threads. So we changed to using 3840 virtual partitions instead.<br /><br />Actually the choice of 240 and 3840 is intricate here. 3840 is equal to 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 3 * 5. This means that if using 12 LQH threads (2 * 2 * 3) then the number of nodes in the cluster should either be on the form 2**n or 5 * 2**n. If not things will still work fine, but load will be slightly unbalanced since the real partitions will contain different numbers of virtual partitions. Uisng 16 LQH partitions the numbers of nodes should be on either of the forms 2**n, 3*2**n, 5*2**n or 3*5*2**n where n is less than or equal to 4. Thus we get from this calculation that 30 nodes is better than 32 nodes if using 16 LQH threads since it brings about a more even distribution of rows in the cluster.<br /><br />With these changes the performance of reads in a distributed environment was quite good and was providing very good scalability. However updates still caused issues.<br /><br />The problem for updates was that the receiver thread handling signals between the nodes in the same node group was overloaded. There was simply too many signals to handle. Much of this was due to some work that was left as a TODO after the 7.0 release since it wasn't an issue in 7.0, but now with the higher throughput it has become an issue.<br /><br />So the solution was to properly implement packing of signals such that several commit messages were packed together and similarly for the commit acknowledge from the API. These straightforward changes decreased the load on the receiver thread to a third and made it possible to push through 1.5M updates per second per node group. It is still possible that this becomes a bottleneck but it should be extremely unusual for a real-world application to reach this state.<br /><br />With all these changes implemented we managed to scale update and read performance linearly up to 30 nodes.</div><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/14455177-2185551902926855242?l=mikaelronstrom.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33217&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33217&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 12:33:00 +0000</pubDate>
    <dc:creator>Mikael Ronstr&amp;ouml;m</dc:creator>
  </item>

  <item>
    <title>Impact of foreign keys absence on replicating slaves</title>
    <guid isPermaLink="false">http://code.openark.org/blog/?p=4860</guid>
    <link>http://code.openark.org/blog/mysql/impact-of-foreign-keys-absence-on-replicating-slaves</link>
    <description>In this post I describe what happens when a slave's Foreign Key setup is different from that of the master. I'm in particular interested in a setup where the slave has a subset of the master's foreign keys, or no foreign keys at all. I wish to observe whether integrity holds.
Making the changes
Which foreign keys do we have and how do we drop them? If you want to do this by hand, well, good luck! Fortunately, common_schema provides with quite a few handy views and routines to assist us. Consider viewing the existing foreign keys on sakila:

master&amp;gt; SELECT create_statement FROM common_schema.sql_foreign_keys WHERE TABLE_SCHEMA='sakila';
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| create_statement                                                                                                                                                                                |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ALTER TABLE `sakila`.`address` ADD CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `sakila`.`city` (`city_id`) ON DELETE RESTRICT ON UPDATE CASCADE                             |
| ALTER TABLE `sakila`.`city` ADD CONSTRAINT `fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `sakila`.`country` (`country_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`customer` ADD CONSTRAINT `fk_customer_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE               |
| ALTER TABLE `sakila`.`customer` ADD CONSTRAINT `fk_customer_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`film` ADD CONSTRAINT `fk_film_language` FOREIGN KEY (`language_id`) REFERENCES `sakila`.`language` (`language_id`) ON DELETE RESTRICT ON UPDATE CASCADE                   |
| ALTER TABLE `sakila`.`film` ADD CONSTRAINT `fk_film_language_original` FOREIGN KEY (`original_language_id`) REFERENCES `sakila`.`language` (`language_id`) ON DELETE RESTRICT ON UPDATE CASCADE |
| ALTER TABLE `sakila`.`film_actor` ADD CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `sakila`.`actor` (`actor_id`) ON DELETE RESTRICT ON UPDATE CASCADE                   |
| ALTER TABLE `sakila`.`film_actor` ADD CONSTRAINT `fk_film_actor_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`film_category` ADD CONSTRAINT `fk_film_category_category` FOREIGN KEY (`category_id`) REFERENCES `sakila`.`category` (`category_id`) ON DELETE RESTRICT ON UPDATE CASCADE |
| ALTER TABLE `sakila`.`film_category` ADD CONSTRAINT `fk_film_category_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                 |
| ALTER TABLE `sakila`.`inventory` ADD CONSTRAINT `fk_inventory_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                         |
| ALTER TABLE `sakila`.`inventory` ADD CONSTRAINT `fk_inventory_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `sakila`.`customer` (`customer_id`) ON DELETE RESTRICT ON UPDATE CASCADE             |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `sakila`.`rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                         |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `sakila`.`customer` (`customer_id`) ON DELETE RESTRICT ON UPDATE CASCADE               |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `sakila`.`inventory` (`inventory_id`) ON DELETE RESTRICT ON UPDATE CASCADE           |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                           |
| ALTER TABLE `sakila`.`staff` ADD CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`staff` ADD CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                             |
| ALTER TABLE `sakila`.`store` ADD CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`store` ADD CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Most of the foreign key constraints use RESTRICT for DELETE (meaning you are not allowed to delete a parent row when children exist), and CASCADE for UPDATE (meaning changes to parent will propagate to children). This is good, since I want to test behavior of both RESTRICT and CASCADE.
OK, we wish to remove these constraints from the slave. To see what we are going to do, consider:

slave1&amp;gt; select drop_statement from common_schema.sql_foreign_keys where table_schema='sakila';
+-----------------------------------------------------------------------------------+
| drop_statement                                                                    |
+-----------------------------------------------------------------------------------+
| ALTER TABLE `sakila`.`address` DROP FOREIGN KEY `fk_address_city`                 |
| ALTER TABLE `sakila`.`city` DROP FOREIGN KEY `fk_city_country`                    |
| ALTER TABLE `sakila`.`customer` DROP FOREIGN KEY `fk_customer_address`            |
| ALTER TABLE `sakila`.`customer` DROP FOREIGN KEY `fk_customer_store`              |
| ALTER TABLE `sakila`.`film` DROP FOREIGN KEY `fk_film_language`                   |
| ALTER TABLE `sakila`.`film` DROP FOREIGN KEY `fk_film_language_original`          |
| ALTER TABLE `sakila`.`film_actor` DROP FOREIGN KEY `fk_film_actor_actor`          |
| ALTER TABLE `sakila`.`film_actor` DROP FOREIGN KEY `fk_film_actor_film`           |
| ALTER TABLE `sakila`.`film_category` DROP FOREIGN KEY `fk_film_category_category` |
| ALTER TABLE `sakila`.`film_category` DROP FOREIGN KEY `fk_film_category_film`     |
| ALTER TABLE `sakila`.`inventory` DROP FOREIGN KEY `fk_inventory_film`             |
| ALTER TABLE `sakila`.`inventory` DROP FOREIGN KEY `fk_inventory_store`            |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_customer`             |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_rental`               |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_staff`                |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_customer`               |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_inventory`              |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_staff`                  |
| ALTER TABLE `sakila`.`staff` DROP FOREIGN KEY `fk_staff_address`                  |
| ALTER TABLE `sakila`.`staff` DROP FOREIGN KEY `fk_staff_store`                    |
| ALTER TABLE `sakila`.`store` DROP FOREIGN KEY `fk_store_address`                  |
| ALTER TABLE `sakila`.`store` DROP FOREIGN KEY `fk_store_staff`                    |
+-----------------------------------------------------------------------------------+

To actually make the DROP, we use common_schema's eval():

slave1&amp;gt; call common_schema.eval(&quot;select drop_statement from common_schema.sql_foreign_keys where table_schema='sakila'&quot;);

eval() is a handy routine which invokes statements generated by the given query.
This concludes the setup part.
Tests will include:

Attempting to delete a parent row
Attempting to add an invalid child row
Attempting to update parent row

I was thinking there would be a difference between the two binary log file formats: STATEMENT and ROW. But the tests I produced showed no difference.
Tests
Attempting to delete parent row:

master&amp;gt; delete from actor where actor_id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`sakila`.`film_actor`, CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) ON UPDATE CASCADE)

slave1&amp;gt; select * from actor where actor_id=1;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        1 | PENELOPE   | GUINESS   | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+

Good: the master refused the DELETE, and no DELETE occurred on slave. Integrity is intact.
Attempting to add an invalid child row:

master&amp;gt; insert into film_actor (actor_id, film_id, last_update) values (9999, 1, NOW());
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`sakila`.`film_actor`, CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) ON UPDATE CASCADE)

slave&amp;gt; select * from film_actor where actor_id=9999;
Empty set (0.00 sec)

Integrity is still intact.
Attempting to update parent row: there is nothing invalid about this operation. I'm wondering whether changes are CASCADEd on slave as well as on master:

master&amp;gt; update actor set actor_id=999 where actor_id=199;

master&amp;gt; select count(*) from film_actor where actor_id=999;
+----------+
| count(*) |
+----------+
|       15 |
+----------+

The 999 value wasn't there before on the master, so this verifies the CASCADE works on master. As for slave:

slave&amp;gt; select count(*) from actor where actor_id=999;
+----------+
| count(*) |
+----------+
|        1 |
+----------+

slave&amp;gt; select count(*) from film_actor where actor_id=999;
+----------+
| count(*) |
+----------+
|        0 |
+----------+

Bummer! The actor's row was updated, but cascading did not work on slave.
This is actually documented. However, the documentation only relates to the issue of slave tables being MyISAM. The problem occurs even when the slave tables are InnoDB, and have no foreign key constraints.
Conclusion
My personal interest in the scenario is due to something I'm working on, I'll elaborate on a future post. People sometime hope to get rid of foreign keys, and might wonder whether replication performance would boost having constraints removed on slaves.
When slave does not enforce foreign keys, you cannot rely on integrity with cascading constraints. An ugly patch might be to use triggers so as to simulate their behavior. Performance wise this is very bad.</description>
    <content:encoded><![CDATA[<p>In this post I describe what happens when a slave's Foreign Key setup is different from that of the master. I'm in particular interested in a setup where the slave has a subset of the master's foreign keys, or no foreign keys at all. I wish to observe whether integrity holds.</p>
<h4>Making the changes</h4>
<p>Which foreign keys do we have and how do we drop them? If you want to do this by hand, well, good luck! Fortunately, <a href="http://code.google.com/p/common-schema/">common_schema</a> provides with quite a few handy views and routines to assist us. Consider viewing the existing foreign keys on <strong>sakila</strong>:</p>
<blockquote>
<pre>master&gt; SELECT <strong>create_statement</strong> FROM <strong>common_schema.sql_foreign_keys</strong> WHERE TABLE_SCHEMA='sakila';
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| create_statement                                                                                                                                                                                |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ALTER TABLE `sakila`.`address` ADD CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `sakila`.`city` (`city_id`) ON DELETE RESTRICT ON UPDATE CASCADE                             |
| ALTER TABLE `sakila`.`city` ADD CONSTRAINT `fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `sakila`.`country` (`country_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`customer` ADD CONSTRAINT `fk_customer_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE               |
| ALTER TABLE `sakila`.`customer` ADD CONSTRAINT `fk_customer_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`film` ADD CONSTRAINT `fk_film_language` FOREIGN KEY (`language_id`) REFERENCES `sakila`.`language` (`language_id`) ON DELETE RESTRICT ON UPDATE CASCADE                   |
| ALTER TABLE `sakila`.`film` ADD CONSTRAINT `fk_film_language_original` FOREIGN KEY (`original_language_id`) REFERENCES `sakila`.`language` (`language_id`) ON DELETE RESTRICT ON UPDATE CASCADE |
| ALTER TABLE `sakila`.`film_actor` ADD CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `sakila`.`actor` (`actor_id`) ON DELETE RESTRICT ON UPDATE CASCADE                   |
| ALTER TABLE `sakila`.`film_actor` ADD CONSTRAINT `fk_film_actor_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`film_category` ADD CONSTRAINT `fk_film_category_category` FOREIGN KEY (`category_id`) REFERENCES `sakila`.`category` (`category_id`) ON DELETE RESTRICT ON UPDATE CASCADE |
| ALTER TABLE `sakila`.`film_category` ADD CONSTRAINT `fk_film_category_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                 |
| ALTER TABLE `sakila`.`inventory` ADD CONSTRAINT `fk_inventory_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                         |
| ALTER TABLE `sakila`.`inventory` ADD CONSTRAINT `fk_inventory_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `sakila`.`customer` (`customer_id`) ON DELETE RESTRICT ON UPDATE CASCADE             |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `sakila`.`rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                         |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `sakila`.`customer` (`customer_id`) ON DELETE RESTRICT ON UPDATE CASCADE               |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `sakila`.`inventory` (`inventory_id`) ON DELETE RESTRICT ON UPDATE CASCADE           |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                           |
| ALTER TABLE `sakila`.`staff` ADD CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`staff` ADD CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                             |
| ALTER TABLE `sakila`.`store` ADD CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`store` ADD CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+</pre>
</blockquote>
<p>Most of the foreign key constraints use <strong>RESTRICT</strong> for <strong>DELETE</strong> (meaning you are not allowed to delete a parent row when children exist), and <strong>CASCADE</strong> for <strong>UPDATE</strong> (meaning changes to parent will propagate to children). This is good, since I want to test behavior of both <strong>RESTRICT</strong> and <strong>CASCADE</strong>.</p>
<p><span></span>OK, we wish to remove these constraints from the slave. To see what we are going to do, consider:</p>
<blockquote>
<pre>slave1&gt; select <strong>drop_statement</strong> from <strong>common_schema.sql_foreign_keys</strong> where table_schema='sakila';
+-----------------------------------------------------------------------------------+
| drop_statement                                                                    |
+-----------------------------------------------------------------------------------+
| ALTER TABLE `sakila`.`address` DROP FOREIGN KEY `fk_address_city`                 |
| ALTER TABLE `sakila`.`city` DROP FOREIGN KEY `fk_city_country`                    |
| ALTER TABLE `sakila`.`customer` DROP FOREIGN KEY `fk_customer_address`            |
| ALTER TABLE `sakila`.`customer` DROP FOREIGN KEY `fk_customer_store`              |
| ALTER TABLE `sakila`.`film` DROP FOREIGN KEY `fk_film_language`                   |
| ALTER TABLE `sakila`.`film` DROP FOREIGN KEY `fk_film_language_original`          |
| ALTER TABLE `sakila`.`film_actor` DROP FOREIGN KEY `fk_film_actor_actor`          |
| ALTER TABLE `sakila`.`film_actor` DROP FOREIGN KEY `fk_film_actor_film`           |
| ALTER TABLE `sakila`.`film_category` DROP FOREIGN KEY `fk_film_category_category` |
| ALTER TABLE `sakila`.`film_category` DROP FOREIGN KEY `fk_film_category_film`     |
| ALTER TABLE `sakila`.`inventory` DROP FOREIGN KEY `fk_inventory_film`             |
| ALTER TABLE `sakila`.`inventory` DROP FOREIGN KEY `fk_inventory_store`            |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_customer`             |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_rental`               |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_staff`                |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_customer`               |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_inventory`              |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_staff`                  |
| ALTER TABLE `sakila`.`staff` DROP FOREIGN KEY `fk_staff_address`                  |
| ALTER TABLE `sakila`.`staff` DROP FOREIGN KEY `fk_staff_store`                    |
| ALTER TABLE `sakila`.`store` DROP FOREIGN KEY `fk_store_address`                  |
| ALTER TABLE `sakila`.`store` DROP FOREIGN KEY `fk_store_staff`                    |
+-----------------------------------------------------------------------------------+</pre>
</blockquote>
<p>To actually make the DROP, we use <em>common_schema</em>'s <a href="http://common-schema.googlecode.com/svn/trunk/common_schema/doc/html/eval.html">eval()</a>:</p>
<blockquote>
<pre>slave1&gt; call <strong>common_schema.eval</strong>("select drop_statement from common_schema.sql_foreign_keys where table_schema='sakila'");</pre>
</blockquote>
<p><em>eval()</em> is a handy routine which invokes statements generated by the given query.</p>
<p>This concludes the setup part.</p>
<p>Tests will include:</p>
<ol>
<li>Attempting to delete a parent row</li>
<li>Attempting to add an invalid child row</li>
<li>Attempting to update parent row</li>
</ol>
<p>I was thinking there would be a difference between the two binary log file formats: <strong>STATEMENT</strong> and <strong>ROW</strong>. But the tests I produced showed no difference.</p>
<h4>Tests</h4>
<p>Attempting to delete parent row:</p>
<blockquote>
<pre>master&gt; delete from actor where actor_id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`sakila`.`film_actor`, CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) ON UPDATE CASCADE)

slave1&gt; select * from actor where actor_id=1;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        1 | PENELOPE   | GUINESS   | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+</pre>
</blockquote>
<p>Good: the master refused the <strong>DELETE</strong>, and no <strong>DELETE</strong> occurred on slave. Integrity is intact.</p>
<p>Attempting to add an invalid child row:</p>
<blockquote>
<pre>master&gt; insert into film_actor (actor_id, film_id, last_update) values (9999, 1, NOW());
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`sakila`.`film_actor`, CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) ON UPDATE CASCADE)

slave&gt; select * from film_actor where actor_id=9999;
Empty set (0.00 sec)</pre>
</blockquote>
<p>Integrity is still intact.</p>
<p>Attempting to update parent row: there is nothing invalid about this operation. I'm wondering whether changes are <strong>CASCADE</strong>d on slave as well as on master:</p>
<blockquote>
<pre>master&gt; update actor set actor_id=999 where actor_id=199;

master&gt; select count(*) from film_actor where actor_id=999;
+----------+
| count(*) |
+----------+
|       15 |
+----------+</pre>
</blockquote>
<p>The <strong>999</strong> value wasn't there before on the master, so this verifies the <strong>CASCADE</strong> works on master. As for slave:</p>
<blockquote>
<pre>slave&gt; select count(*) from actor where actor_id=999;
+----------+
| count(*) |
+----------+
|        1 |
+----------+

slave&gt; select count(*) from film_actor where actor_id=999;
+----------+
| count(*) |
+----------+
|        0 |
+----------+</pre>
</blockquote>
<p>Bummer! The actor's row was updated, but cascading did not work on slave.</p>
<p>This is actually <a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-and-mysql-replication.html">documented</a>. However, the documentation only relates to the issue of slave tables being <strong>MyISAM</strong>. The problem occurs even when the slave tables are <strong>InnoDB</strong>, and have no foreign key constraints.</p>
<h4>Conclusion</h4>
<p>My personal interest in the scenario is due to something I'm working on, I'll elaborate on a future post. People sometime hope to get rid of foreign keys, and might wonder whether replication performance would boost having constraints removed on slaves.</p>
<p>When slave does not enforce foreign keys, you cannot rely on integrity with cascading constraints. An ugly patch might be to use triggers so as to <a href="http://code.openark.org/blog/mysql/triggers-use-case-compilation-part-i">simulate their behavior</a>. Performance wise this is very bad.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33215&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33215&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Mon, 14 May 2012 05:52:41 +0000</pubDate>
    <dc:creator>Shlomi Noach</dc:creator>
    <category>MySQL</category>
    <category>common_schema</category>
    <category>data integrity</category>
  </item>

  <item>
    <title>How to run a flawless technical demo</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-16959946.post-2905215843321231746</guid>
    <link>http://datacharmer.blogspot.com/2012/05/how-to-run-flawless-technical-demo.html</link>
    <description>Why demos?For as long as I can remember in my public speaking activities, I have always planned my presentations with some sort of live demo in it. I am always surprised when a conference venue asks me to provide my slides in advance, to be loaded in an anonymous computer with no chance of demos. I always turn down such offers, as I always want to provide a demo.There have been times when technical or time constraints prevented me from demoing something, and in these cases I felt that the presentation was lacking a vital part. But I always try. I have even given demos during lightning talks, and those were the ones that made me feel really good.I have given hundreds of presentations, and hundreds of demos, and as in every human activity, I have made plenty of mistakes. I believe I have learned some valuable lesson from my mistakes, and this article is my attempt at sharing the joy with wannabe presenters and also with presenters who want to embrace this method.So, why having a (risky) live demo in your presentation? Here are some of the reasons that may also appeal to you.Show trust in your productYou want to talk about your product. The audience assumes that you have confidence in whichever product you want to talk about. However, if you limit your presentation to showing slides, no matter how beautiful and dynamic they are, the audience will be left with the dormant impression that you were talking about something not really trustworthy, or even (gasp!) unreal. If your audience start thinking that you are dealing with vaporware, nothing can dispel that thought faster and more convincingly than a demo. If you trust your product, then you should demo it. If you don't include a demo because you are afraid that the demo would fail, then don't present the topic. It's as simple as that.Improve the entertainment level of your presentationA demo makes a presentation more lively. The audience sees that you abandon the comfortable protection of your slide deck, where you are totally in control, and you risk your hide with a live demo of something that (as any technological artifact) can fail and blow up on your face, burning your reputation and your ego at the same time. Entertainment in a presentation is very important. As Guy Kawasaki said [1], if you make your presentation full of important things, chances are that people will forget all of them because your presentation will be boring, but if your make your presentation entertaining, then you can easily sneak in some important stuff, and the audience will remember that.increase your reputation as a guruIncluding live demos in your presentation will make the audience think of you as some sort of guru, and your reputation will grow. Now, I don't do demos for this reason. As I said before, I like presenting technical things with live examples. And then I realized that people attending my presentations had a high opinion of me, because of my demos. If not your reputation, live demos will increase your self confidence, and sometimes they amount to the same thing.Demos DOs and DON&amp;#8217;TsDown to business. A demo is not a casual happening. A successful demo has a long story behind it.When you are on stage with a demo, you are not a boring presenter. You are a magician pulling rabbits from a top hat. You are a gymnast showing your dexterity. You are the center of attention, and success is within your grasp.All this comes at a price, though. Read on.DO: Master the topicFirst and foremost. You must be really comfortable with the topic being presented. If you aren&amp;#8217;t, it shows, and the audience will feel your fear. Therefore, the first requirement for a good demo is that you really understand what you are doing, and why. Not only because you are unlikely to demo successfully something that you don&amp;#8217;t fully understand, but also because you will fall at the first question from the audience. (Incidentally, if a presenter maneuvers the presentation to prevent questions, it may be a sign of lack of self confidence, or even downright ignorance.)DO: make a plan of what you want to showKnowing your stuff doesn&amp;#8217;t mean that you can convey your enthusiasm for the product to the audience just by showing some random commands. You must decide beforehand what you want to demo, and design a set of steps to follow during the demo. Think of the reasons why you believe your product is wonderful, and try to define these reasons as a set of examples that will make the audience share your feelings.DO: include in the demo your product&amp;#8217;s best featuresWhen you plan, you have to give the audience the amazing stuff. If your slides claim that your product can make men walk on water, you will have to bring an inflatable pool on stage, fill it with water, bare your feet, and take a stroll in front of everyone. That&amp;#8217;s a bit extreme, as we are dealing with software here, and your claims are, hopefully, less daring, but you get the gist. If you claim features that could be compared to walking on water, be prepared to show the miracle.Whatever it is that your product has promised, you must show it live. The audience won&amp;#8217;t be satisfied by your demo of secondary marvelous features if you don&amp;#8217;t show evidence of your primary goods. There are exceptions, of course. If your goods require 30 minutes of processing to show their full potential, you can&amp;#8217;t show all of it live. But you may try to give a reduced demo of whatever can be achieved in the time allotted for your presentation. One thing that I often do is start the presentation with a short demo where I get the process started, inform the audience that this process will take 30 minutes, and then get on with the slide show. 30 minutes later, I resume the demo, explain what has happened in the meantime, and finally I show the magic part. This is simple, honest, and very effective.DO: PracticeYour experience with the product is not enough to guarantee a good demo. You must make sure that:What you want to demo is actually feasible. If you promise something that your product can&amp;#8217;t deliver, there is no amount of penance that can save your reputation;You know how to perform the tasks that you have planned;The tasks happen in a predictable way, so that you know that a given sequence of events will end up with the result that you want.There are no side effects determined by other tasks running in your computer (or computers) that will prevent a positive result.This means that you will repeat the demo several times, until you are satisfied that nothing can surprise you, and everything goes as planned. This phase is very important for you, and also for your product. You are likely to find important bugs when getting ready for a demo. Two birds with a stone!DO: Time it!Your time for a demo is short. No matter how much you want to show your product live, you can&amp;#8217;t go beyond the time allotted for the whole presentation. More realistically, your demo will last from 1/4 to 2/3 of the presentation, with 1/3 being the more common duration. Thus, you need to make sure that your demo doesn&amp;#8217;t run out of time. Especially if your punch line is at the end of your demo, you won&amp;#8217;t be able to show it if the attendees are rushing from your room to attend the next presentation.Have a plan BDespite your preparation, there are things that may happen that will keep you longer than expected at your demo, and you may find yourself short of time. Then you need to have an alternative demo plan, i.e. a shorter demo that you can show from that moment on instead of the original one. What this means is that you need to practice two plans. And maybe three. Such is life!DO: Practice some more - Make sure your demo is visibleWhen you practice, you are looking at your computer and you may think that what you see is the same thing that your audience will see. Don&amp;#8217;t make this assumption! When you are on stage, things are much different from what you see at home.In person, in a large ballroomWhen you are using a projector, or an external screen, you may have a different experience from what you had at home or at the office, with your dedicated 24in screen, where you did prepare a beautiful demo. If the projector has a maximum resolution of 1024x768 (which is quite common nowadays) or even 800x600, you must review your demo, and be ready to scale down your ambitions. What you need to do:find out in advance, days or weeks before the presentation, if possible, what kind of projector you will be dealing with, and try to test with the same resolution.When you are at the venue, test with the projector before the presentation, and make sure that your demo is visible from every seat in the room. Adjust your demo if needed.If there is no advance testing time allocated, grab an apple or a sandwich and do it at breakfast or lunch time. Skipping a meal is less important than risking your reputation.Online, when giving a webinarWhen you are presenting online, in addition to the resolution of the software delivering your webinar, there is also the possibility of more limitations or complex setups that will stand in the way of a successful demo. You will need to test the webinar software, possibly with two computers: one to deliver the demo, and one to check what another attendee would see. Don&amp;#8217;t ever accept a denial along the lines of &amp;#8220;we can&amp;#8217;t do a dry run, but the software is a piece of cake, nothing can go wrong.&amp;#8221; You know that everything can go wrong, so insist and make sure that you get testing time. Cancel the demo if you can&amp;#8217;t get it.DON&amp;#8217;T: make mistakesThis seems an unnecessary recommendation. It goes together with Practice your demo. But we need to stress some points in the matter of mistakes. There are simple mistakes, like misspelling a command when you are typing (I do a lot of SEELCT instead of SELECT), but this kind of mistakes are not the ones that get you in trouble. They may even increase the audience awareness that they are witnessing a live event, The mistakes you must avoid are the ones that make the demo fail; the ones that may show your lack of familiarity with the product (which won&amp;#8217;t happen if you have been practicing). Therefore: focus on the task, and you will win.There are, though, mistakes that you can include in your demo. If one of your product&amp;#8217;s features is the ability to recover from mistakes, you can include such mistakes in your demo, provided that:You tell the audience beforehand that you are going to make a deliberate mistake, just to show how your product can save your butt. (You may also try the theatrical trick of making the error and then emphatically announce that you did that on purpose. The result really depends on how good your theatrics are.)You include this mistake in your demo plan, and you practice it as thoroughly as you did the rest.DON&amp;#8217;T: Run other applications in background during the demoDepending on the product you are showing, there are many ways of spoiling the demo through applications that run when they should not. Let me give you a non-comprehensive list:A Skype balloon saying I miss you honey bunny will not improve your credibility;Twitter and Facebook notifications with more or less embarrassing remarks should be also avoided;Your computer starts a file reindex when you are showing a resource intensive task using three virtual machines, and performance drops to a crawl;The remote server that you are using for your demo goes down for maintenance;A planned backup starts in youd database server right when you need it to be responsive at its best;A daily test starts on your remote server, and removes your demo setup.There are more, and more. If you can think of it, t may happen!DON&amp;#8217;T: Deviate from your well rehearsed scriptOnce you have defined a demo plan, stick to it. Make no exceptions. If you must make exceptions, you must plan for them as well. Therefore: make no exceptions. This recommendation closely resembles the next one.DON&amp;#8217;T: Make some brilliant improvements at the last minuteYou are an expert in your field, and an expert of the product that you are presenting. You may also be one of the developers of that project. It is thus very natural and common that you think of improvements that will make your product behave much better. That&amp;#8217;s good and commendable. But don&amp;#8217;t make these changes on the build that you will use for the demo. NEVER. EVER.I did it. A few times. And I regretted it. Every time.If you make a change, then you must have time to test the whole demo from scratch, more than once, or else you must wait to apply your changes after the demo. Similarly, you may think of an improvement of the demo. If that implies deviating from the plan that you have tested, don&amp;#8217;t do it, unless you have time to test the whole demo again with the change.Summing upDoing a live demo is a lot of work, and what you show on stage is only a tiny part of the work involved. But I can assure you that the thrill of having a flawless demo that amazes the audience is deeply fulfilling. I recommend it to all the public speakers.Try it. And then you will be hooked. At my company, we all are. I don&amp;#8217;t remember where I read it, as I have read many books and articles by Guy Kawasaki, but I think it was in Reality Check. &amp;#160;&amp;#8617;</description>
    <content:encoded><![CDATA[<h2>Why demos?</h2><p>For as long as I can remember in my public speaking activities, I have always planned my presentations with some sort of live demo in it. I am always surprised when a conference venue asks me to provide my slides in advance, to be loaded in an anonymous computer with no chance of demos. I always turn down such offers, as I always want to provide a demo.</p><p>There have been times when technical or time constraints prevented me from demoing something, and in these cases I felt that the presentation was lacking a vital part. But I always try. I have even given demos during lightning talks, and those were the ones that made me feel really good.</p><p>I have given hundreds of presentations, and hundreds of demos, and as in every human activity, I have made plenty of mistakes. I believe I have learned some valuable lesson from my mistakes, and this article is my attempt at sharing the joy with wannabe presenters and also with presenters who want to embrace this method.</p><p>So, why having a (risky) live demo in your presentation? Here are some of the reasons that may also appeal to you.</p><h3>Show trust in your product</h3><p>You want to talk about your product. The audience assumes that you have confidence in whichever product you want to talk about. However, if you limit your presentation to showing slides, no matter how beautiful and dynamic they are, the audience will be left with the dormant impression that you were talking about something not really trustworthy, or even (gasp!) unreal. If your audience start thinking that you are dealing with vaporware, nothing can dispel that thought faster and more convincingly than a demo. If you trust your product, then you should demo it. If you don't include a demo because you are afraid that the demo would fail, then don't present the topic. It's as simple as that.</p><h3>Improve the entertainment level of your presentation</h3><p>A demo makes a presentation more lively. The audience sees that you abandon the comfortable protection of your slide deck, where you are totally in control, and you risk your hide with a live demo of something that (as any technological artifact) can fail and blow up on your face, burning your reputation and your ego at the same time. Entertainment in a presentation is very important. As Guy Kawasaki said <a href="http://datacharmer.blogspot.com/#fn:1" title="see footnote">[1]</a>, if you make your presentation full of important things, chances are that people will forget all of them because your presentation will be boring, but if your make your presentation entertaining, then you can easily sneak in some important stuff, and the audience will remember that.</p><h3>increase your reputation as a guru</h3><p>Including live demos in your presentation will make the audience think of you as some sort of guru, and your reputation will grow. Now, I don't do demos for this reason. As I said before, I like presenting technical things with live examples. And then I realized that people attending my presentations had a high opinion of me, because of my demos. If not your reputation, live demos will increase your self confidence, and sometimes they amount to the same thing.</p><h2>Demos DOs and DON&#8217;Ts</h2><p>Down to business. A demo is not a casual happening. A successful demo has a long story behind it.</p><p>When you are on stage with a demo, you are not a boring presenter. You are a magician pulling rabbits from a top hat. You are a gymnast showing your dexterity. You are the center of attention, and success is within your grasp.</p><p>All this comes at a price, though. Read on.</p><h3>DO: Master the topic</h3><p>First and foremost. You must be really comfortable with the topic being presented. If you aren&#8217;t, it shows, and the audience will <em>feel your fear</em>. Therefore, the first requirement for a good demo is that you really understand what you are doing, and why. Not only because you are unlikely to demo successfully something that you don&#8217;t fully understand, but also because you will fall at the first question from the audience. (Incidentally, if a presenter maneuvers the presentation to prevent questions, it may be a sign of lack of self confidence, or even downright ignorance.)</p><h3>DO: make a plan of what you want to show</h3><p>Knowing your stuff doesn&#8217;t mean that you can convey your enthusiasm for the product to the audience just by showing some random commands. You must decide beforehand what you want to demo, and design a set of steps to follow during the demo. Think of the reasons why you believe your product is wonderful, and try to define these reasons as a set of examples that will make the audience share your feelings.</p><h3>DO: include in the demo your product&#8217;s best features</h3><p>When you plan, you have to give the audience the amazing stuff. If your slides claim that your product can make men walk on water, you will have to bring an inflatable pool on stage, fill it with water, bare your feet, and take a stroll in front of everyone. That&#8217;s a bit extreme, as we are dealing with software here, and your claims are, hopefully, less daring, but you get the gist. If you claim features that could be compared to walking on water, be prepared to show the miracle.</p><p>Whatever it is that your product has promised, you must show it live. The audience won&#8217;t be satisfied by your demo of secondary marvelous features if you don&#8217;t show evidence of your primary goods. There are exceptions, of course. If your goods require 30 minutes of processing to show their full potential, you can&#8217;t show all of it live. But you may try to give a reduced demo of whatever can be achieved in the time allotted for your presentation. One thing that I often do is start the presentation with a short demo where I get the process started, inform the audience that this process will take 30 minutes, and then get on with the slide show. 30 minutes later, I resume the demo, explain what has happened in the meantime, and finally I show the magic part. This is simple, honest, and very effective.</p><h3>DO: Practice</h3><p>Your experience with the product is not enough to guarantee a good demo. You must make sure that:</p><ul><li>What you want to demo is actually feasible. If you promise something that your product can&#8217;t deliver, there is no amount of penance that can save your reputation;</li><li>You know how to perform the tasks that you have planned;</li><li>The tasks happen in a predictable way, so that you know that a given sequence of events will end up with the result that you want.</li><li>There are no side effects determined by other tasks running in your computer (or computers) that will prevent a positive result.</li></ul><p>This means that you will repeat the demo several times, until you are satisfied that nothing can surprise you, and everything goes as planned. This phase is very important for you, and also for your product. You are likely to find important bugs when getting ready for a demo. Two birds with a stone!</p><h3>DO: Time it!</h3><p>Your time for a demo is short. No matter how much you want to show your product live, you can&#8217;t go beyond the time allotted for the whole presentation. More realistically, your demo will last from 1/4 to 2/3 of the presentation, with 1/3 being the more common duration. Thus, you need to make sure that your demo doesn&#8217;t run out of time. Especially if your punch line is at the end of your demo, you won&#8217;t be able to show it if the attendees are rushing from your room to attend the next presentation.</p><h3>Have a plan B</h3><p>Despite your preparation, there are things that may happen that will keep you longer than expected at your demo, and you may find yourself short of time. Then you need to have an alternative demo plan, i.e. a shorter demo that you can show from that moment on instead of the original one. What this means is that you need to practice two plans. And maybe three. Such is life!</p><h3>DO: Practice some more - Make sure your demo is visible</h3><p>When you practice, you are looking at your computer and you may think that what you see is the same thing that your audience will see. Don&#8217;t make this assumption! When you are on stage, things are much different from what you see at home.</p><h4>In person, in a large ballroom</h4><p>When you are using a projector, or an external screen, you may have a different experience from what you had at home or at the office, with your dedicated 24in screen, where you did prepare a beautiful demo. If the projector has a maximum resolution of 1024x768 (which is quite common nowadays) or even 800x600, you must review your demo, and be ready to scale down your ambitions. What you need to do:</p><ul><li>find out in advance, days or weeks before the presentation, if possible, what kind of projector you will be dealing with, and try to test with the same resolution.</li><li>When you are at the venue, test with the projector before the presentation, and make sure that your demo is visible from every seat in the room. Adjust your demo if needed.</li><li>If there is no advance testing time allocated, grab an apple or a sandwich and do it at breakfast or lunch time. Skipping a meal is less important than risking your reputation.</li></ul><h4>Online, when giving a webinar</h4><p>When you are presenting online, in addition to the resolution of the software delivering your webinar, there is also the possibility of more limitations or complex setups that will stand in the way of a successful demo. You will need to test the webinar software, possibly with two computers: one to deliver the demo, and one to check what another attendee would see. Don&#8217;t ever accept a denial along the lines of &#8220;we can&#8217;t do a dry run, but the software is a piece of cake, nothing can go wrong.&#8221; You know that everything can go wrong, so insist and make sure that you get testing time. Cancel the demo if you can&#8217;t get it.</p><h3>DON&#8217;T: make mistakes</h3><p>This seems an unnecessary recommendation. It goes together with <em>Practice your demo</em>. But we need to stress some points in the matter of mistakes. There are simple mistakes, like misspelling a command when you are typing (I do a lot of SEELCT instead of SELECT), but this kind of mistakes are not the ones that get you in trouble. They may even increase the audience awareness that they are witnessing a live event, </p><p>The mistakes you must avoid are the ones that make the demo fail; the ones that may show your lack of familiarity with the product (which won&#8217;t happen if you have been practicing). Therefore: focus on the task, and you will win.</p><p>There are, though, mistakes that you can include in your demo. If one of your product&#8217;s features is the ability to recover from mistakes, you can include such mistakes in your demo, provided that:</p><ul><li>You tell the audience beforehand that you are going to make a deliberate mistake, just to show how your product can save your butt. (You may also try the theatrical trick of making the error and then emphatically announce that you did that on purpose. The result really depends on how good your theatrics are.)</li><li>You include this mistake in your demo plan, and you practice it as thoroughly as you did the rest.</li></ul><h3>DON&#8217;T: Run other applications in background during the demo</h3><p>Depending on the product you are showing, there are many ways of spoiling the demo through applications that run when they should not. Let me give you a non-comprehensive list:</p><ul><li>A Skype balloon saying <em>I miss you honey bunny</em> will not improve your credibility;</li><li>Twitter and Facebook notifications with more or less embarrassing remarks should be also avoided;</li><li>Your computer starts a file reindex when you are showing a resource intensive task using three virtual machines, and performance drops to a crawl;</li><li>The remote server that you are using for your demo goes down for maintenance;</li><li>A planned backup starts in youd database server right when you need it to be responsive at its best;</li><li>A daily test starts on your remote server, and removes your demo setup.</li></ul><p>There are more, and more. If you can think of it, t may happen!</p><h3>DON&#8217;T: Deviate from your well rehearsed script</h3><p>Once you have defined a demo plan, stick to it. Make no exceptions. If you must make exceptions, you must plan for them as well. Therefore: make no exceptions. This recommendation closely resembles the next one.</p><h3>DON&#8217;T: Make some brilliant improvements at the last minute</h3><p>You are an expert in your field, and an expert of the product that you are presenting. You may also be one of the developers of that project. It is thus very natural and common that you think of improvements that will make your product behave much better. That&#8217;s good and commendable. But don&#8217;t make these changes on the build that you will use for the demo. NEVER. EVER.</p><p>I did it. A few times. And I regretted it. Every time.</p><p>If you make a change, then you must have time to test the whole demo from scratch, more than once, or else you must wait to apply your changes after the demo. Similarly, you may think of an improvement of the demo. If that implies deviating from the plan that you have tested, don&#8217;t do it, unless you have time to test the whole demo again with the change.</p><h2>Summing up</h2><p>Doing a live demo is a lot of work, and what you show on stage is only a tiny part of the work involved. But I can assure you that the thrill of having a flawless demo that amazes the audience is deeply fulfilling. I recommend it to all the public speakers.</p><p>Try it. And then you will be hooked. At my <a href="http://continuent.com">company</a>, we all are.</p><div><hr /><ol><li> <p>I don&#8217;t remember where I read it, as I have read many books and articles by Guy Kawasaki, but I think it was in <em>Reality Check</em>. <a href="http://datacharmer.blogspot.com/#fnref:1" title="return to article">&#160;&#8617;</a></p></li></ol></div><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/16959946-2905215843321231746?l=datacharmer.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33213&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33213&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Sun, 13 May 2012 19:44:00 +0000</pubDate>
    <dc:creator>Giuseppe Maxia</dc:creator>
    <category>presentations</category>
    <category>conference</category>
    <category>mysql</category>
    <category>database</category>
    <category>presentation</category>
  </item>

  <item>
    <title>SQL Injection at Reddit</title>
    <guid isPermaLink="false">651 at http://www.sheeri.com</guid>
    <link>http://www.sheeri.com/content/sql-injection-reddit</link>
    <description>Reddit takes SQL injection very seriously.
How seriously?
Check their headers:
scabral-07890:~ scabral$ curl --head www.reddit.com
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Set-Cookie: reddit_first=%7B%22organic_pos%22%3A%201%2C%20%22firsttime%22%3A%20%22first%22%7D; Domain=reddit.com; expires=Thu, 31 Dec 2037 23:59:59 GMT; Path=/
Server: '; DROP TABLE servertypes; --
Date: Sat, 12 May 2012 13:54:20 GMT
Connection: keep-alive
scabral-07890:~ scabral$ 
A colleague at PICC showed me this when he learned of my talk on MySQL security!</description>
    <content:encoded><![CDATA[<p><a href="http://www.reddit.com">Reddit</a> takes SQL injection very seriously.</p>
<p>How seriously?</p>
<p>Check their headers:</p>
<p><code>scabral-07890:~ scabral$ curl --head <a href="http://www.reddit.com" title="www.reddit.com">www.reddit.com</a><br />
</code><code>HTTP/1.1 200 OK<br />
</code><code>Content-Type: text/html; charset=UTF-8<br />
</code><code>Set-Cookie: reddit_first=%7B%22organic_pos%22%3A%201%2C%20%22firsttime%22%3A%20%22first%22%7D; Domain=reddit.com; expires=Thu, 31 Dec 2037 23:59:59 GMT; Path=/<br />
</code><code>Server: '; DROP TABLE servertypes; --<br />
</code><code>Date: Sat, 12 May 2012 13:54:20 GMT<br />
</code><code>Connection: keep-alive</code></p>
<p><code>scabral-07890:~ scabral$ </code></p>
<p>A colleague at <a href="http://www.picconf.org/">PICC</a> showed me this when he learned of my talk on MySQL security!</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33211&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33211&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Sat, 12 May 2012 14:03:54 +0000</pubDate>
    <dc:creator>Sheeri K. Cabral</dc:creator>
  </item>

  <item>
    <title>OurSQL Episode 90: Handle With Care</title>
    <guid isPermaLink="false">1162 at http://technocation.org</guid>
    <link>http://technocation.org/content/oursql-episode-90%3A-handle-care</link>
    <description>This week we present how to use pt-archiver and pt-find, two Percona Toolkit tools. We focus on the common usage of the tools and the gotchas we ran into using them.
News/Events/Feedback
Conferences:
MySQL Innovation Day Schedule Tuesday June 5th, Redwood Shores, CA. Register here (free). Content will be available via live stream, so save the date!
read more</description>
    <content:encoded><![CDATA[<p>This week we present how to use <a href="http://technocation.org/allcontent/www.percona.com/doc/percona-toolkit/2.1/pt-archiver.html">pt-archiver</a> and <a href="http://technocation.org/allcontent/www.percona.com/doc/percona-toolkit/2.1/pt-find.html">pt-find</a>, two <a href="http://www.percona.com/doc/percona-toolkit/">Percona Toolkit</a> tools. We focus on the common usage of the tools and the gotchas we ran into using them.</p>
<p><strong>News/Events/Feedback</strong><br />
Conferences:<br />
<A>MySQL Innovation Day Schedule</A> Tuesday June 5th, Redwood Shores, CA. <a href="http://www.oracle.com/webapps/events/ns/EventsDetail.jsp?p_eventId=151000&amp;src=7590517&amp;src=7590517&amp;Act=4">Register here (free)</a>. Content will be available via live stream, so save the date!</p>
<p><a href="http://technocation.org/content/oursql-episode-90%3A-handle-care">read more</a></p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33209&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33209&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Fri, 11 May 2012 20:42:37 +0000</pubDate>
    <dc:creator>Technocation</dc:creator>
    <category>Podcasts</category>
    <category>General</category>
  </item>

  <item>
    <title>Portuguese Planet</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-3812360659149323517.post-5142284173805655086</guid>
    <link>http://sqlhjalp.blogspot.com/2012/05/portuguese-planet.html</link>
    <description>A big welcome to the Portuguese MySQL Community.&amp;nbsp; The MySQL team has recognized your support of MySQL, so we hope you can take advantage of the new&amp;nbsp; Portuguese MySQL Planet.&amp;nbsp; Wagner has started us off with his blogs so please feel free to submit your Portuguese Feeds.</description>
    <content:encoded><![CDATA[A big welcome to the <a href="http://pt.planet.mysql.com/">Portuguese MySQL Community</a>.&nbsp; The MySQL team has recognized your support of MySQL, so we hope you can take advantage of the new&nbsp;<a href="http://pt.planet.mysql.com/"> Portuguese MySQL Planet</a>.&nbsp; <a href="http://apex.oracle.com/pls/otn/f?p=19297:4:204549980188701::NO:4:P4_ID:4541">Wagner</a> has started us off with his blogs so please feel free to submit your <a href="http://pt.planet.mysql.com/new">Portuguese Feeds</a>.<div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/3812360659149323517-5142284173805655086?l=sqlhjalp.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33208&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33208&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Fri, 11 May 2012 20:05:00 +0000</pubDate>
    <dc:creator>Keith Larson</dc:creator>
  </item>

  <item>
    <title>Workaround for ‘Authentication failed’ Issue When Connecting through HTTP Tunnel</title>
    <guid isPermaLink="false">http://blogs.devart.com/dbforge/?p=2447</guid>
    <link>http://blogs.devart.com/dbforge/workaround-for-authentication-failed-issue-when-connecting-through-http-tunnel.html</link>
    <description>Some of our users have encountered problems with establishing a connection over the tunnel.php script despite the fact that the tunnel.php script is installed correctly. The following error message occurs:
&amp;#8216;Can&amp;#8217;t connect to MySQL server on &amp;#8216;your.sitename.com&amp;#8217; (10061): Authentication failed.&amp;#8217;
The problem appears to be with cached proxy servers and will be fixed in one of the next builds of our product.
Currently it can be fixed by replacing the dbforgemysql.exe.config file, that can be found in dbForge Studio for MySQL installation folder, with the attached one.</description>
    <content:encoded><![CDATA[<p>Some of our users have encountered <strong>problems</strong> with establishing a connection over the <strong>tunnel.php</strong> script despite the fact that the tunnel.php script is installed correctly. The following error message occurs:</p>
<p><span>&#8216;Can&#8217;t connect to MySQL server on &#8216;your.sitename.com&#8217; (10061): Authentication failed.&#8217;</span></p>
<p>The problem appears to be with <strong>cached proxy servers</strong> and will be fixed in one of the next builds of our product.</p>
<p>Currently it can be fixed by replacing the <a href="http://blogs.devart.com/dbforge/wp-content/uploads/2012/04/dbforgemysql.exe.config.zip">dbforgemysql.exe.config</a> file, that can be found in dbForge Studio for MySQL installation folder, with the attached one.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33197&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33197&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Fri, 11 May 2012 14:50:11 +0000</pubDate>
    <dc:creator>Julia Samarska</dc:creator>
    <category>MySQL</category>
    <category>HTTP tunnel</category>
  </item>

  <item>
    <title>History of MySQL Cluster architecture development</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-14455177.post-6059051990425460485</guid>
    <link>http://mikaelronstrom.blogspot.com/2012/05/history-of-mysql-cluster-architecture.html</link>
    <description>With the release of MySQL Cluster 7.2.5 we've released a version of MySQL Cluster where each data node is capable of using up to 51 threads in total. This is a remarkable feat for a product that only a few years ago was purely single-threaded. This article tries to explain what it is in the MySQL Cluster architecture that makes it so scalable to new HW demands.The MySQL Cluster architecture is based on a design that is used in the world's most sold telecom switch, the AXE switch. This switch is used in all mobile networks delivered by Ericsson. MySQL Cluster also originates from Ericsson. The architecture of the AXE switch was developed in reaction to an older switch that had quality issues since there were too many global variables and too little modularity. The architecture was inspired by how HW was designed. In HW design each module can only communicate with other HW modules using signals (mostly electrical). The idea of the AXE architecture was to use this architecture also for software. The basic concept of this architecture is blocks and signals. Blocks are the software modules (similar to a HW module). Each block is self-contained and contains all the data and code for its needs. There is no shared data with other blocks. So the only method to get access to data in another block is to send a signal to the block requesting the data.When the storage engine of MySQL Cluster, NDB Cluster was designed, the AXE architecture was used, so the NDB DBMS software contains a set of blocks (currently a little more than 20) that communicate with each other using signals.This is the first reason why it is so easy to make MySQL Cluster scale to many CPUs. Since each block only communicates with each other through signals it means that it's trivial to move blocks between different threads unless they are using signals that are immediate and have dependency on returning to the sender block in the same state as when the signal was sent. The NDB blocks have a number of blocks that are not possible to split, these are LQH (Local Query Handler, handles communication between data storage and indexes, handles scans), TUP (data storage), ACC (hash index), TUX (ordered index) and some parts of TSMAN, PGMAN and LGMAN (tablespace, page and log management for disk data). There is however no such dependency between TC and the Local Data Manager blocks (LDM), also the handling of asynchronous replication is in a separate block that can be easily moved to any thread. We also have a number of schema management blocks that have been separated into their own threads using some special lock techniques. Thus we have already from functional division a separation into the LDM domain, the TC domain, the SPJ domain, the schema management domain, the asynchronous replication domain. Currently TC and SPJ are colocated although it's not really necessary, but TC and SPJ are extremely easy to scale since each transaction is independent of the other. Thus we have 4 thread domains and each of these can be placed into separate domains.In MySQL Cluster 6.3 and previous version everything was done in one single thread and this configuration is still supported since it has nice real-time characteristics when everything is placed into one thread. In MySQL Cluster 7.0, the LDM blocks were separated from the rest of the blocks into separate threads. In addition the schema management blocks and the TC and SPJ domain was separated into one domain. Asynchronous replication was also separated into its own thread domain. Finally given that all of these threads requires communication with the outside world we also created a separate receive thread that receives data on TCP sockets and converts the data into prepackaged signals that the blocks can execute and puts them onto a queue to the thread that will execute the signals. We spent considerable effort in making the implementation of communication between threads extremely efficient and this communication is entirely lock-free and uses memory barriers and careful writing and reading to communicate with each other. On x86-machines this part is partly implemented in assembler to make efficient use of optimal assembler instructions.The LDM used yet one more technique to distribute these blocks onto several threads. It makes use of the partitioning that NDB Cluster already supports, also the REDO log in NDB Cluster was also already separated into 4 log parts and thus it was straightforward to create 4 LDM modules where each block is replicated within different threads. Each LDM instance takes care of one part of the data stored in the data node. From the outside the protocol is still the same although the address of a block now also contains thread id in addition to the node id and block id. The block reference already contained space enough for this purpose so no change to the block code was required to handle this.In MySQL Cluster 7.2 we have advanced the threading yet one more step. The first step was to separate the schema management domain from the TC and SPJ domain. Then given that TC can be partitioned to handle different transactions using a simple round robin allocation scheme, we also separated the TC domain into multiple threads. In principle there is no limit to how many TC threads we could use, we pick a number which is appropriate to the CPU requirements of the TC domain. We selected 16 as the maximum number since we've found no scenario where more TC threads are required. We also extended the number of LDM instances to a maximum of 16 by also extending the possible number of log parts to 16.The next step was to create multiple receiver threads. This was relatively easy as well by partitioning the threads to handle different sockets (one socket is used to communicate with each other node in the cluster).Another step we also took was to separate the send call from the block threads. Thus special send threads can be used, this increases latency slightly but improves throughput. It also minimizes the risk of bottlenecks occurring in the data nodes. We set the maximum of send threads to 8 and similarly for receive threads. Normally 3 threads should suffice for even the biggest configuration to some extent dependent on the efficiency of the OS read and write syscalls.Thus what we can see is that the choice of a block and signal architecture have made it possible for us with very small means to bring data node scalability from 1 CPU, onwards to 8 and now onwards to at least 40. Even more can be achieved. Thus MySQL Cluster is based on a SW architecture which can easily accomodate itself to the new HW developed. It has also from the first codeline had the concept of efficient communication in its genes. The first prototype of NDB Cluster developed in 1994 used two SPARC-stations interconnected with Dolphin SCI technology. The current benchmarks we've executed used Infiniband with 56Gb/s interconnects where latency is extremely short when communicating between different machines.The next generation of HW is likely to revolutionize handling of memory. MySQL Cluster is well prepared for this as well.Last a small historical anecdote. In the 1990's the HW vendors had a race to deliver GHz cpus. The x86 CPU sold early 1990 was the 80486 that run at 25MHz. In 1999 the race was over when the first GHz processor was delivered. We released MySQL Cluster 7.2 two months ago running at 17.6MHz. We're soon announcing the next major improvement to this number. So will the 2010's be the decade where the race is on for which DBMS that can first deliver a GHz query execution? MySQL Cluster is well prepared for such a challenge.</description>
    <content:encoded><![CDATA[<div dir="ltr" trbidi="on">With the release of MySQL Cluster 7.2.5 we've released a version of MySQL Cluster where each data node is capable of using up to 51 threads in total. This is a remarkable feat for a product that only a few years ago was purely single-threaded. This article tries to explain what it is in the MySQL Cluster architecture that makes it so scalable to new HW demands.<br /><br />The MySQL Cluster architecture is based on a design that is used in the world's most sold telecom switch, the AXE switch. This switch is used in all mobile networks delivered by Ericsson. MySQL Cluster also originates from Ericsson. The architecture of the AXE switch was developed in reaction to an older switch that had quality issues since there were too many global variables and too little modularity. The architecture was inspired by how HW was designed. In HW design each module can only communicate with other HW modules using signals (mostly electrical). The idea of the AXE architecture was to use this architecture also for software. The basic concept of this architecture is blocks and signals. Blocks are the software modules (similar to a HW module). Each block is self-contained and contains all the data and code for its needs. There is no shared data with other blocks. So the only method to get access to data in another block is to send a signal to the block requesting the data.<br /><br />When the storage engine of MySQL Cluster, NDB Cluster was designed, the AXE architecture was used, so the NDB DBMS software contains a set of blocks (currently a little more than 20) that communicate with each other using signals.<br /><br />This is the first reason why it is so easy to make MySQL Cluster scale to many CPUs. Since each block only communicates with each other through signals it means that it's trivial to move blocks between different threads unless they are using signals that are immediate and have dependency on returning to the sender block in the same state as when the signal was sent. The NDB blocks have a number of blocks that are not possible to split, these are LQH (Local Query Handler, handles communication between data storage and indexes, handles scans), TUP (data storage), ACC (hash index), TUX (ordered index) and some parts of TSMAN, PGMAN and LGMAN (tablespace, page and log management for disk data). There is however no such dependency between TC and the Local Data Manager blocks (LDM), also the handling of asynchronous replication is in a separate block that can be easily moved to any thread. We also have a number of schema management blocks that have been separated into their own threads using some special lock techniques. Thus we have already from functional division a separation into the LDM domain, the TC domain, the SPJ domain, the schema management domain, the asynchronous replication domain. Currently TC and SPJ are colocated although it's not really necessary, but TC and SPJ are extremely easy to scale since each transaction is independent of the other. Thus we have 4 thread domains and each of these can be placed into separate domains.<br /><br />In MySQL Cluster 6.3 and previous version everything was done in one single thread and this configuration is still supported since it has nice real-time characteristics when everything is placed into one thread. In MySQL Cluster 7.0, the LDM blocks were separated from the rest of the blocks into separate threads. In addition the schema management blocks and the TC and SPJ domain was separated into one domain. Asynchronous replication was also separated into its own thread domain. Finally given that all of these threads requires communication with the outside world we also created a separate receive thread that receives data on TCP sockets and converts the data into prepackaged signals that the blocks can execute and puts them onto a queue to the thread that will execute the signals. We spent considerable effort in making the implementation of communication between threads extremely efficient and this communication is entirely lock-free and uses memory barriers and careful writing and reading to communicate with each other. On x86-machines this part is partly implemented in assembler to make efficient use of optimal assembler instructions.<br /><br />The LDM used yet one more technique to distribute these blocks onto several threads. It makes use of the partitioning that NDB Cluster already supports, also the REDO log in NDB Cluster was also already separated into 4 log parts and thus it was straightforward to create 4 LDM modules where each block is replicated within different threads. Each LDM instance takes care of one part of the data stored in the data node. From the outside the protocol is still the same although the address of a block now also contains thread id in addition to the node id and block id. The block reference already contained space enough for this purpose so no change to the block code was required to handle this.<br /><br />In MySQL Cluster 7.2 we have advanced the threading yet one more step. The first step was to separate the schema management domain from the TC and SPJ domain. Then given that TC can be partitioned to handle different transactions using a simple round robin allocation scheme, we also separated the TC domain into multiple threads. In principle there is no limit to how many TC threads we could use, we pick a number which is appropriate to the CPU requirements of the TC domain. We selected 16 as the maximum number since we've found no scenario where more TC threads are required. We also extended the number of LDM instances to a maximum of 16 by also extending the possible number of log parts to 16.<br /><br />The next step was to create multiple receiver threads. This was relatively easy as well by partitioning the threads to handle different sockets (one socket is used to communicate with each other node in the cluster).<br /><br />Another step we also took was to separate the send call from the block threads. Thus special send threads can be used, this increases latency slightly but improves throughput. It also minimizes the risk of bottlenecks occurring in the data nodes. We set the maximum of send threads to 8 and similarly for receive threads. Normally 3 threads should suffice for even the biggest configuration to some extent dependent on the efficiency of the OS read and write syscalls.<br /><br />Thus what we can see is that the choice of a block and signal architecture have made it possible for us with very small means to bring data node scalability from 1 CPU, onwards to 8 and now onwards to at least 40. Even more can be achieved. Thus MySQL Cluster is based on a SW architecture which can easily accomodate itself to the new HW developed. It has also from the first codeline had the concept of efficient communication in its genes. The first prototype of NDB Cluster developed in 1994 used two SPARC-stations interconnected with Dolphin SCI technology. The current benchmarks we've executed used Infiniband with 56Gb/s interconnects where latency is extremely short when communicating between different machines.<br /><br />The next generation of HW is likely to revolutionize handling of memory. MySQL Cluster is well prepared for this as well.<br /><br />Last a small historical anecdote. In the 1990's the HW vendors had a race to deliver GHz cpus. The x86 CPU sold early 1990 was the 80486 that run at 25MHz. In 1999 the race was over when the first GHz processor was delivered. We released MySQL Cluster 7.2 two months ago running at 17.6MHz. We're soon announcing the next major improvement to this number. So will the 2010's be the decade where the race is on for which DBMS that can first deliver a GHz query execution? MySQL Cluster is well prepared for such a challenge.</div><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/14455177-6059051990425460485?l=mikaelronstrom.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33196&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33196&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Fri, 11 May 2012 13:26:00 +0000</pubDate>
    <dc:creator>Mikael Ronstr&amp;ouml;m</dc:creator>
  </item>

  <item>
    <title>MySQL Cluster: mysqld Sort aborted and error 4006</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-19281624.post-6723360930498270072</guid>
    <link>http://johanandersson.blogspot.com/2012/05/mysql-cluster-mysqld-sort-aborted-and.html</link>
    <description>Just a note on a problem that some people may find useful and may work for you if you have the same issue.A client had a problem this morning with queries being aborted with the error message:&amp;nbsp;Got temporary error 4006 'Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)' from NDBCLUSTERHere you would think that increasing the number of&amp;nbsp;MaxNoOfConcurrentTransactions would help, but the root cause is something else (the client is not even close of hitting the default&amp;nbsp;MaxNoOfConcurrentTransactions)It turned out that during the night a couple of updates to the schema had been made (ALTER TABLEs to convert a couple of TEXT to &amp;nbsp;VARCHAR, so that a particular index could be created).Looking in the mysql error logs we had:120511 10:47:05 [ERROR] /usr/local/mysql/bin/mysqld: Sort aborted: Got temporary error 4006 'Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)' from NDBCLUSTER120511 10:47:27 [ERROR] Got error 4006 when reading table './database_name/table_name'I suspected there was something wrong (corrupted?) with the .frm files that the mysql server is caching in the datadir, and simply did, for all mysql servers:stop mysqldremove all .frm for all ndb tables in the databasestart mysqldand finally a &quot;SHOW TABLES&quot; to get all the .frm files back up from the data nodes into the local datadir of the mysqldNow, the problem is gone, but I can't explain how reading a table can cause error 4006...Hope this helps someone.</description>
    <content:encoded><![CDATA[<br />Just a note on a problem that some people may find useful and may work for you if you have the same issue.<br /><br />A client had a problem this morning with queries being aborted with the error message:<br /><br /><span>&nbsp;Got temporary error 4006 'Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)' from NDBCLUSTER</span><br /><br />Here you would think that increasing the number of&nbsp;MaxNoOfConcurrentTransactions would help, but the root cause is something else (the client is not even close of hitting the default&nbsp;MaxNoOfConcurrentTransactions)<br /><br />It turned out that during the night a couple of updates to the schema had been made (ALTER TABLEs to convert a couple of TEXT to &nbsp;VARCHAR, so that a particular index could be created).<br /><br />Looking in the mysql error logs we had:<br /><br /><span>120511 10:47:05 [ERROR] /usr/local/mysql/bin/mysqld: Sort aborted: Got temporary error 4006 'Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)' from NDBCLUSTER</span><br /><span>120511 10:47:27 [ERROR] Got error 4006 when reading table './database_name/table_name</span>'<br /><br />I suspected there was something wrong (corrupted?) with the .frm files that the mysql server is caching in the datadir, and simply did, for all mysql servers:<br /><br /><ul><li>stop mysqld</li><li>remove all .frm for all ndb tables in the database</li><li>start mysqld</li><li>and finally a "SHOW TABLES" to get all the .frm files back up from the data nodes into the local datadir of the mysqld</li></ul><div>Now, the problem is gone, but I can't explain how reading a table can cause error 4006...</div><div><br /></div><div>Hope this helps someone.</div><div><br /></div><div><br /></div><br /><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/19281624-6723360930498270072?l=johanandersson.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33195&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33195&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Fri, 11 May 2012 12:55:00 +0000</pubDate>
    <dc:creator>Johan Andersson</dc:creator>
  </item>

  <item>
    <title>Upscene Productions is celebrating Ten Years of Database Development Tools</title>
    <guid isPermaLink="false">E6D8E9DE-F9F2-4569-B77C-8142E49BB32D</guid>
    <link>http://www.upscene.com</link>
    <description>Upscene Productions is celebrating it's 10 year anniversary with a massive discount on all our products: 70% discount until the end of May.

We produce database development, management and testing tools for:
* Oracle
* Microsoft SQL Server
* MySQL
* InterBase
* Firebird
* SQL Anywhere
* NexusDB
* Advantage Database
* Generic connectivity tools for ADO and ODBC

These include test data generator tools, database design and development tools, auditing tools, a dbExpress driver for Firebird, debugging tools, performance analysis tools.

Coupon code TENYEARS will get you this discount, check www.upscene.com for more information.</description>
    <content:encoded><![CDATA[<a href="http://www.upscene.com" target="_blank">Upscene Productions</a> is celebrating it's 10 year anniversary with a massive discount on all our products: 70% discount until the end of May.<br />
<br />
We produce database development, management and testing tools for:<br />
* Oracle<br />
* Microsoft SQL Server<br />
* MySQL<br />
* InterBase<br />
* Firebird<br />
* SQL Anywhere<br />
* NexusDB<br />
* Advantage Database<br />
* Generic connectivity tools for ADO and ODBC<br />
<br />
These include test data generator tools, database design and development tools, auditing tools, a dbExpress driver for Firebird, debugging tools, performance analysis tools.<br />
<br />
Coupon code TENYEARS will get you this discount, check <a href="http://www.upscene.com" target="_blank">www.upscene.com</a> for more information.<br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33193&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33193&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Fri, 11 May 2012 07:42:51 +0000</pubDate>
    <dc:creator>Martijn Tonies</dc:creator>
  </item>

  <item>
    <title>Log Buffer #271, A Carnival of the Vanities for DBAs</title>
    <guid isPermaLink="false">http://www.pythian.com/news/?p=32801</guid>
    <link>http://www.pythian.com/news/32801/log-buffer-271-a-carnival-of-the-vanities-for-dbas/</link>
    <description>They say, “April showers bring May flowers.”  They basically say that nature brings different things in different colors aimed at improving the things. That is so true for the blogging world too. This Log Buffer Edition also brings out different blog posts to improve things, so enjoy the Log Buffer #271. Oracle: One of world&amp;#8217;s [...]</description>
    <content:encoded><![CDATA[They say, “April showers bring May flowers.”  They basically say that nature brings different things in different colors aimed at improving the things. That is so true for the blogging world too. This Log Buffer Edition also brings out different blog posts to improve things, so enjoy the Log Buffer #271. Oracle: One of world&#8217;s [...]<br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33192&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33192&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Fri, 11 May 2012 07:00:14 +0000</pubDate>
    <dc:creator>The Pythian Group</dc:creator>
    <category>Log Buffer</category>
    <category>MySQL</category>
    <category>Oracle</category>
    <category>SQL Server</category>
  </item>

  <item>
    <title>Newbie: User and Host question</title>
    <guid isPermaLink="false">http://opensourcedba.wordpress.com/?p=796</guid>
    <link>http://opensourcedba.wordpress.com/2012/05/10/newbie-user-and-host-question/</link>
    <description>Today on MySql Forums, there was a question in the newbie section about two users  &amp;#8212; I have a doubt on db host and db user relationship . What does this mean ? 


name
host


tom
%


joe
127.0.0.1


New DBAs are often confused by the quirky methods of authentication that MySQL uses.   Heck, extremely experienced MySQL DBAs can get confused.
From the manual, 6.2.4. Access Control, Stage 1: Connection Verification
When you attempt to connect to a MySQL server, the server accepts or rejects the connection based on your identity and whether you can verify your identity by supplying the correct password. If not, the server denies access to you completely. Otherwise, the server accepts the connection, and then enters Stage 2 and waits for requests.
Your identity is based on two pieces of information:
    The client host from which you connect
    Your MySQL user name

So the first user, Tom, is allowed to connect from &amp;#8216;%&amp;#8217; and &amp;#8216;%&amp;#8217; is a wildcard for any system.  And the second user is only allowed to connect from a host with the address &amp;#8217;127.0.0.1&amp;#8242;.  Usually systems have a network loop-back (think short circuit) assigned to 127.0.0.1 and uses that for its own traffic internally1.
Also from the same manual page (abbreviated) to provide a little more clarity.
The following table shows how various combinations of Host and User values in the user table apply to incoming connections.


Host Value
User Value
Permissible Connections

&amp;#8216;thomas.loc.gov&amp;#8217;
&amp;#8216;fred&amp;#8217;
	fred, connecting from thomas.loc.gov

&amp;#8216;thomas.loc.gov&amp;#8217;
&amp;#8221;
 	Any user, connecting from thomas.loc.gov

&amp;#8216;%&amp;#8217;
&amp;#8216;fred&amp;#8217;
	fred, connecting from any host

&amp;#8216;%&amp;#8217;
&amp;#8221;
 	Any user, connecting from any host

&amp;#8216;%.loc.gov&amp;#8217;
&amp;#8216;fred&amp;#8217;
 	fred, connecting from any host in the loc.gov domain


It helps to occasionally re-read the The MySQL Access Privilege System of the manual to help remember how users get into the system as well as the edge cases. It is all too easy to set up multiple users with the same user name value but different privileges depending on where they connect. 
And thanks to all who take the time to answer questions on the forums!

 Hugh simplification used here for brevity.

         </description>
    <content:encoded><![CDATA[<p>Today on <a href="http://forums.mysql.com" target="_blank">MySql Forums</a>, there was a question in the <a href="http://forums.mysql.com/read.php?10,533027,533027#msg-533027" target="_blank">newbie section</a> about two users  &#8212; <em>I have a doubt on db host and db user relationship . What does this mean ? </em></p>
<table width="50%">
<tr>
<th>name</th>
<th>host</th>
</tr>
<tr>
<td>tom</td>
<td>%</td>
</tr>
<tr>
<td>joe</td>
<td>127.0.0.1</td>
</tr>
</table>
<p>New DBAs are often confused by the quirky methods of authentication that MySQL uses.   Heck, extremely experienced MySQL DBAs can get confused.</p>
<p>From the manual, <a href="http://dev.mysql.com/doc/refman/5.6/en/connection-access.html" target="_blank">6.2.4. Access Control, Stage 1: Connection Verification</a></p>
<blockquote><p>When you attempt to connect to a MySQL server, the server accepts or rejects the connection based on your identity and whether you can verify your identity by supplying the correct password. If not, the server denies access to you completely. Otherwise, the server accepts the connection, and then enters Stage 2 and waits for requests.</p>
<p>Your identity is based on two pieces of information:</p>
<p>    The client host from which you connect</p>
<p>    Your MySQL user name
</p></blockquote>
<p>So the first user, Tom, is allowed to connect from &#8216;%&#8217; and &#8216;%&#8217; is a wildcard for <em>any</em> system.  And the second user is only allowed to connect from a host with the address &#8217;127.0.0.1&#8242;.  Usually systems have a network loop-back (think short circuit) assigned to 127.0.0.1 and uses that for its own traffic internally<sup>1</sup>.</p>
<p>Also from the same manual page (abbreviated) to provide a little more clarity.</p>
<blockquote><p>The following table shows how various combinations of Host and User values in the user table apply to incoming connections.</p>
<table>
<tr>
<th>Host Value
<th>User Value
<th>Permissible Connections</p>
<tr>
<td>&#8216;thomas.loc.gov&#8217;
<td>&#8216;fred&#8217;
<td>	fred, connecting from thomas.loc.gov</p>
<tr>
<td>&#8216;thomas.loc.gov&#8217;
<td>&#8221;
<td> 	Any user, connecting from thomas.loc.gov</p>
<tr>
<td>&#8216;%&#8217;
<td>&#8216;fred&#8217;
<td>	fred, connecting from any host</p>
<tr>
<td>&#8216;%&#8217;
<td>&#8221;
<td> 	Any user, connecting from any host</p>
<tr>
<td>&#8216;%.loc.gov&#8217;
<td>&#8216;fred&#8217;
<td> 	fred, connecting from any host in the loc.gov domain<br />
</table>
</blockquote>
<p>It helps to occasionally re-read the <a href="http://dev.mysql.com/doc/refman/5.6/en/privilege-system.html" target="_blank">The MySQL Access Privilege System</a> of the manual to help remember how users get into the system as well as the edge cases. It is all too easy to set up multiple users with the same user name value but different privileges depending on where they connect. </p>
<p>And thanks to all who take the time to answer questions on the forums!</p>
<ol>
<li> Hugh simplification used here for brevity.</li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/opensourcedba.wordpress.com/796/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/opensourcedba.wordpress.com/796/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/opensourcedba.wordpress.com/796/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/opensourcedba.wordpress.com/796/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/opensourcedba.wordpress.com/796/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/opensourcedba.wordpress.com/796/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/opensourcedba.wordpress.com/796/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/opensourcedba.wordpress.com/796/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/opensourcedba.wordpress.com/796/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/opensourcedba.wordpress.com/796/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/opensourcedba.wordpress.com/796/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/opensourcedba.wordpress.com/796/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/opensourcedba.wordpress.com/796/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/opensourcedba.wordpress.com/796/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=opensourcedba.wordpress.com&amp;blog=15386988&amp;post=796&amp;subd=opensourcedba&amp;ref=&amp;feed=1" width="1" height="1" /><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33191&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33191&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 20:40:47 +0000</pubDate>
    <dc:creator>Dave Stokes</dc:creator>
    <category>Basics</category>
  </item>

  <item>
    <title>Testing Fusion-io ioDrive2 Duo</title>
    <guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=9466</guid>
    <link>http://www.mysqlperformanceblog.com/2012/05/10/testing-fusion-io-iodrive2-duo/</link>
    <description>I was lucky enough to get my hands on new Fusion-io ioDrive2 Duo card. So I decided to run the same series of tests I did for other Flash devices. This is ioDrive2 Duo 2.4TB card and it is visible to OS as two devices (1.2TB each), which can be connected together via software RAID. So I tested in two modes: single drive, and software RAID-0 over two drives.

I should note that to run this card you need to have an external power, by the same reason I mentioned in the previous post: PCIe slot can provide only 25W power, which is not enough for ioDrive2 Duo to provide full performance. I mention this, as it may be challenge for some servers: some models may not have connector for external power, and for some you may need special &amp;#8220;power kit&amp;#8221;. So you need to make sure you have compatible hardware before getting Duo card. I personally ended up with setup like this: I use a separate power supply.
Fusion-io ioDrive2 Firmware v6.0.0, rev 107004 Public, Fusion-io driver version: 3.1.1.
Now to the results.
For this test I also use Cisco UCS C250 server, and on the graph I show the results for both single card and raid (Duo).
Random writes, async:

We see stable and predictable write performance, with throughput: 660 MiB/s for single, and 1300 MiB/s for Duo
Random reads:

Again both modes provides stable level of throughput. 1350 MiB/s for single and 2300 MiB/s for Duo.
Now with separation per thread for random read synchronous IO:


There is also excellent response time characteristics. 0.25ms and 0.19ms for 8 threads, single and Duo cases.
In general ioDrive2 seems to provide better and more stable performance results comparing to previous generation ioDrive.
Follow @VadimTk
</description>
    <content:encoded><![CDATA[<p>I was lucky enough to get my hands on new Fusion-io ioDrive2 Duo card. So I decided to run the same series of tests I did for <a href="http://www.mysqlperformanceblog.com/2012/05/07/testing-fusion-io-iodrive-now-with-driver-3-1/">other Flash devices</a>. This is ioDrive2 Duo 2.4TB card and it is visible to OS as two devices (1.2TB each), which can be connected together via software RAID. So I tested in two modes: single drive, and software RAID-0 over two drives.<br />
<span></span><br />
I should note that to run this card you need to have an external power, by the same reason I mentioned in <a href="http://www.mysqlperformanceblog.com/2012/05/04/testing-virident-flashmax-1400/">the previous post</a>: PCIe slot can provide only 25W power, which is not enough for ioDrive2 Duo to provide full performance. I mention this, as it may be challenge for some servers: some models may not have connector for external power, and for some you may need special &#8220;power kit&#8221;. So you need to make sure you have compatible hardware before getting Duo card. I personally ended up with setup like this: I use <a href="http://dl.dropbox.com/u/9893083/ppt/SSD/DSCF6739.JPG">a separate power supply</a>.</p>
<p>Fusion-io ioDrive2 Firmware v6.0.0, rev 107004 Public, Fusion-io driver version: 3.1.1.</p>
<p>Now to the results.<br />
For this test I also use <a href="http://www.percona.com/docs/wiki/benchmark%3Ahardware%3Acisco_ucs_c250">Cisco UCS C250</a> server, and on the graph I show the results for both single card and raid (Duo).</p>
<p>Random writes, async:<br />
<a href="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/rand-write4.png"><img src="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/rand-write4.png" alt="" title="rand-write" width="640" height="396" class="aligncenter size-full wp-image-9468" /></a></p>
<p>We see stable and predictable write performance, with throughput: <strong>660 MiB/s</strong> for single, and <strong>1300 MiB/s</strong> for Duo</p>
<p>Random reads:<br />
<a href="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/rand-read3.png"><img src="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/rand-read3.png" alt="" title="rand-read" width="640" height="396" class="aligncenter size-full wp-image-9467" /></a></p>
<p>Again both modes provides stable level of throughput. <strong>1350 MiB/s</strong> for single and <strong>2300 MiB/s</strong> for Duo.</p>
<p>Now with separation per thread for random read synchronous IO:<br />
<a href="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/read-sync-thrp1.png"><img src="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/read-sync-thrp1.png" alt="" title="read-sync-thrp" width="640" height="396" class="aligncenter size-full wp-image-9470" /></a></p>
<p><a href="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/read-sync-rt-1.png"><img src="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/read-sync-rt-1.png" alt="" title="read-sync-rt " width="640" height="396" class="aligncenter size-full wp-image-9471" /></a></p>
<p>There is also excellent response time characteristics. <strong>0.25ms and 0.19ms</strong> for 8 threads, single and Duo cases.</p>
<p>In general ioDrive2 seems to provide better and more stable performance results comparing to <a href="http://www.mysqlperformanceblog.com/2012/05/07/testing-fusion-io-iodrive-now-with-driver-3-1/">previous generation ioDrive</a>.</p>
<p><a href="https://twitter.com/VadimTk" data-show-count="false">Follow @VadimTk</a><br />
</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33190&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33190&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 20:30:05 +0000</pubDate>
    <dc:creator>MySQL Performance Blog</dc:creator>
    <category>Benchmarks</category>
    <category>Hardware and Storage</category>
    <category>MySQL</category>
  </item>

  <item>
    <title>Circus Oraclimus Installatus Upgradimus</title>
    <guid isPermaLink="false">http://www.webyog.com/blog/?p=3740</guid>
    <link>http://www.webyog.com/blog/2012/05/10/circus-oraclimus-installatus-upgradimus/</link>
    <description>Circus Oraclimus is back in town.  It was last time only four weeks ago and a few months before that as well, and while it the first few times was quite funny to watch the clowns, it  does not remain funny to see the same absurd tricks over and over again.
I am referring to this: http://bugs.mysql.com/bug.php?id=56889.
If you have both MySQL 5.5 and 5.6 installed on the same Windows system using the .msi installer you cannot upgrade 5.5.  The 5.5 installer refuses to run claiming that a &amp;#8216;newer version&amp;#8217; [of 5.5.x] is installed.  It never was &amp;#8211; and still is not &amp;#8211; a problem upgrading 5.1. with 5.5 (and 5.6) installed.  So this is a bug and it is verified. And it was actually fixed by Vladislav Vaintrub before he left Oracle for Monty Program 1½ years ago.  For some reason the fix failed to be committed and never was included with the installers distributed.  I did several attempts to wake up the people at Oracle asking them to find that patch and commit it to where it should be. It never did lead anywhere.  Not even to a reply.
Needless to say the MariaDB .msi installers for Windows  do not suffer from this.  You can upgrade any MariaDb version with a higher version installed.  But .msi installers for MariaDB are also maintained by Vladislav Vaintrub!
So what you need to do is before upgrading your Oracle/MySQL 5.5 instance if you also have 5.6 installed is to uninstall 5.6, upgrade 5.5 and install 5.6 again (I am not running the configuration wizard as I want to keep the 5.5 and 5.6 configurations I have).  A little annoying, but no data or configuration is lost and after all it takes only 10 minutes.  So not a big deal.  Untill the situation worsended significantly recently (after 5.5.20).
We continue here: http://bugs.mysql.com/bug.php?id=64909
The above uninstall-upgrade-install procedure stopped working for me when upgrading to 5.5.22 and .23.  Both my 5.5 and 5.6 instances become non-functional.  On 5,5 the `mysql` database lost some tables and on 5.6 the service was removed from the system.
It is 4 weeks ago I upgraded to 5.5.23 (that is what I refer to as last visit from Circus Oraclimus) and now I see 5.5.24 is available on mirrors.  Welcome back, Circus Oraclimus! I hope you bring some artists this time and not just the clowns!
( I know perfectly well that that I can install the service very simple for instance with the &amp;#8220;mysqld install servicename&amp;#8221; -command and don&amp;#8217;t need to use the installers.  However like most Windows users I like a unified and consolidated view of what is installed on the system &amp;#8211; in case in &amp;#8220;Control Panel .. Programs&amp;#8221; &amp;#8211; just like most users of &amp;#8216;Red Hat type&amp;#8217; Linux prefer to install using the RPM for exactly the same reason)
&amp;nbsp;


Tweet
</description>
    <content:encoded><![CDATA[<p>Circus Oraclimus is back in town.  It was last time only four weeks ago and a few months before that as well, and while it the first few times was quite funny to watch the clowns, it  does not remain funny to see the same absurd tricks over and over again.</p>
<p>I am referring to this: <a href="http://bugs.mysql.com/bug.php?id=56889">http://bugs.mysql.com/bug.php?id=56889</a>.</p>
<p>If you have both MySQL 5.5 and 5.6 installed on the same Windows system using the .msi installer you cannot upgrade 5.5.  The 5.5 installer refuses to run claiming that a &#8216;newer version&#8217; [of 5.5.x] is installed.  It never was &#8211; and still is not &#8211; a problem upgrading 5.1. with 5.5 (and 5.6) installed.  So this is a bug and it is verified. And it was actually fixed by Vladislav Vaintrub before he left Oracle for Monty Program 1½ years ago.  For some reason the fix failed to be committed and never was included with the installers distributed.  I did several attempts to wake up the people at Oracle asking them to find that patch and commit it to where it should be. It never did lead anywhere.  Not even to a reply.</p>
<p>Needless to say the MariaDB .msi installers for Windows  do not suffer from this.  You can upgrade any MariaDb version with a higher version installed.  But .msi installers for MariaDB are also maintained by Vladislav Vaintrub!</p>
<p>So what you need to do is before upgrading your Oracle/MySQL 5.5 instance if you also have 5.6 installed is to uninstall 5.6, upgrade 5.5 and install 5.6 again (I am <strong>not</strong> running the configuration wizard as I want to keep the 5.5 and 5.6 configurations I have).  A little annoying, but no data or configuration is lost and after all it takes only 10 minutes.  So not a big deal.  Untill the situation worsended significantly recently (after 5.5.20).</p>
<p>We continue here: <a href="http://bugs.mysql.com/bug.php?id=64909">http://bugs.mysql.com/bug.php?id=64909</a></p>
<p>The above uninstall-upgrade-install procedure stopped working for me when upgrading to 5.5.22 and .23.  Both my 5.5 and 5.6 instances become non-functional.  On 5,5 the `mysql` database lost some tables and on 5.6 the service was removed from the system.</p>
<p>It is 4 weeks ago I upgraded to 5.5.23 (that is what I refer to as last visit from Circus Oraclimus) and now I see 5.5.24 is available on mirrors.  Welcome back, Circus Oraclimus! I hope you bring some artists this time and not just the clowns!</p>
<p>( I know perfectly well that that I can install the service very simple for instance with the &#8220;mysqld install servicename&#8221; -command and don&#8217;t need to use the installers.  However like most Windows users I like a unified and consolidated view of what is installed on the system &#8211; in case in &#8220;Control Panel .. Programs&#8221; &#8211; just like most users of &#8216;Red Hat type&#8217; Linux prefer to install using the RPM for exactly the same reason)</p>
<p>&nbsp;</p>

<!-- This is the start of the WP Twitter Button code -->
<div><a href="http://twitter.com/share" data-url="http://www.webyog.com/blog/2012/05/10/circus-oraclimus-installatus-upgradimus/" data-count="horizontal" data-via="webyog">Tweet</a></div>
<!-- This is the end of the WP Twitter Button code --><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33189&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33189&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 19:20:47 +0000</pubDate>
    <dc:creator>Webyog</dc:creator>
    <category>MySQL</category>
  </item>

  <item>
    <title>Installing Apache2 With PHP5 And MySQL Support On Ubuntu 12.04 LTS (LAMP)</title>
    <guid isPermaLink="false">http://www.howtoforge.com/installing-apache2-with-php5-and-mysql-support-on-ubuntu-12.04-lts-lamp</guid>
    <link>http://www.howtoforge.com/installing-apache2-with-php5-and-mysql-support-on-ubuntu-12.04-lts-lamp</link>
    <description>Installing Apache2 With PHP5 And MySQL Support On Ubuntu 12.04 LTS (LAMP)

 LAMP is short for Linux, Apache, MySQL, PHP.
This tutorial shows how you can install an Apache2 webserver on an
Ubuntu 12.04 LTS server with PHP5 support (mod_php) and MySQL support.</description>
    <content:encoded><![CDATA[<table align="left" cellpadding="0" cellspacing="0" width="42" height="40"><tr><td><img class="teaser-image-odd" src="http://static.howtoforge.com/images/teaser/ubuntu.gif" width="39" height="40" alt="" /></td></tr></table><p><b>Installing Apache2 With PHP5 And MySQL Support On Ubuntu 12.04 LTS (LAMP)</b></p>

<p> LAMP is short for <b>L</b>inux, <b>A</b>pache, <b>M</b>ySQL, <b>P</b>HP.
This tutorial shows how you can install an Apache2 webserver on an
Ubuntu 12.04 LTS server with PHP5 support (mod_php) and MySQL support.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33188&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33188&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 16:45:06 +0000</pubDate>
    <category>Ubuntu</category>
    <category>Web Server</category>
    <category>Apache</category>
    <category>MySQL</category>
    <category>PHP</category>
  </item>

  <item>
    <title>Percona Live Slides and Video Available: The Right Read Optimization is Actually Write Optimization</title>
    <guid isPermaLink="false">http://www.tokutek.com/?p=4104</guid>
    <link>http://www.tokutek.com/2012/05/percona-live-slides-and-video-available-the-right-read-optimization-is-actually-write-optimization/</link>
    <description>In April, I got to give a talk at Percona Live, about why The Right Read Optimization is Actually Write Optimization.  It was my first industry talk, so I was delighted when someone in the audience said &amp;#8220;I feel like I just earned a college credit.&amp;#8221;
Box offered to host everyone&amp;#8217;s slides from the conference here (mine is here).  A big thanks from me to Sheeri Cabral, for recording my talk and posting it online!

The focus of the talk starts with why write optimization is what you want to do in many situations, especially if you need read optimization.  Then I get in to some of the theory on optimizing writes by laying out your data better on disk.  We approach this gradually, beginning with how B-trees work and progressing with a few simple rules for getting better performance, and see some of the tradeoffs inherent in these techniques.</description>
    <content:encoded><![CDATA[<p>In April, I got to give a talk at <a href="http://www.percona.com/live/mysql-conference-2012/" target="_blank">Percona Live</a>, about why The Right Read Optimization is Actually Write Optimization.  It was my first industry talk, so I was delighted when someone in the audience said <a href="https://twitter.com/#!/sheeri/statuses/190253402926743553" target="_blank">&#8220;I feel like I just earned a college credit.&#8221;</a></p>
<p>Box offered to host everyone&#8217;s slides from the conference <a href="https://www.box.com/perconalive2012/1/262276476#/s/0090e784768a747b437f/1/212680542" target="_blank">here</a> (mine is <a href="https://www.box.com/s/0090e784768a747b437f/1/262276476/2092583755/1" target="_blank">here</a>).  A big thanks from me to <a href="http://sheeri.net" target="_blank">Sheeri Cabral</a>, for recording my talk and <a href="http://www.youtube.com/watch?v=q6BnG74FZMQ" target="_blank">posting it online</a>!</p>
<p></p>
<p>The focus of the talk starts with why write optimization is what you want to do in many situations, especially if you need read optimization.  Then I get in to some of the theory on optimizing writes by laying out your data better on disk.  We approach this gradually, beginning with how B-trees work and progressing with a few simple rules for getting better performance, and see some of the tradeoffs inherent in these techniques.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33187&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33187&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 14:06:33 +0000</pubDate>
    <dc:creator>Tokuview Blog</dc:creator>
    <category>TokuView</category>
    <category>B-tree</category>
    <category>big data</category>
    <category>Fractal Tree indexes</category>
    <category>mysql</category>
    <category>NewSQL</category>
    <category>percona</category>
    <category>TokuDB</category>
    <category>Tokutek</category>
  </item>

  <item>
    <title>Hardware Components Failures — Survey Results</title>
    <guid isPermaLink="false">http://www.pythian.com/news/?p=32793</guid>
    <link>http://www.pythian.com/news/32793/hardware-components-failures-survey-results/</link>
    <description>When preparing for the the IOUG Collaborate 12 deep dive on deploying Oracle Databases for high Availability, I wanted to provide some feedback on what hardware components are failing most frequently and which ones are less frequently. I believe I have reasonably good idea about that but I thought that providing some more objective data [...]</description>
    <content:encoded><![CDATA[When preparing for the the IOUG Collaborate 12 deep dive on deploying Oracle Databases for high Availability, I wanted to provide some feedback on what hardware components are failing most frequently and which ones are less frequently. I believe I have reasonably good idea about that but I thought that providing some more objective data [...]<br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33186&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33186&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 13:14:17 +0000</pubDate>
    <dc:creator>Alex Gorbachev</dc:creator>
    <category>MySQL</category>
    <category>Oracle</category>
    <category>SQL Server</category>
    <category>Technical Blog</category>
    <category>failure</category>
    <category>hardware</category>
    <category>high availability</category>
    <category>polls</category>
  </item>

  <item>
    <title>MySQL training dates by SkySQL Training!</title>
    <guid isPermaLink="false">967 at http://www.skysql.com</guid>
    <link>http://www.skysql.com/blogs/max-mether/mysql-training-dates-skysql-training</link>
    <description>&amp;nbsp;

	The good news is that we have just released plenty of MariaDB &amp;amp; MySQL training dates covering the summer months and even into October across the globe.&amp;nbsp;

	&amp;nbsp;

	This new training calendar includes all of our current training courses in plenty of locations both in North America and Europe.&amp;nbsp;

	&amp;nbsp;

	You can chose from the following training options:



			Administering a MySQL Database

			Administering MySQL Cluster

			Developing Applications with the MySQL Database

			High Availability for the MySQL Database

			Performance Tuning for the MySQL Database



	You are of course always welcome to request courses in new locations and we will be happy to set these up for you. Onsite courses are also available, wherever you are.&amp;nbsp;

	&amp;nbsp;

	While setting up these new training dates, we have also been working on an overhaul of all our courses with updates to include new versions and in some cases new products. More details about these changes will follow soon in a separate blog entry.

	&amp;nbsp;

	In the meantime, you can check out our new training calendar:&amp;nbsp;http://www.skysql.com/services/training/schedule</description>
    <content:encoded><![CDATA[<p>&nbsp;</p>
<div>
	The good news is that we have just released plenty of <a href="http://www.skysql.com/services/training/schedule">MariaDB &amp; MySQL training dates</a> covering the summer months and even into October across the globe.&nbsp;</div>
<div>
	&nbsp;</div>
<div>
	This <a href="http://www.skysql.com/services/training/schedule">new training calendar</a> includes all of our current training courses in plenty of locations both in North America and Europe.&nbsp;</div>
<div>
	&nbsp;</div>
<div>
	You can chose from the following <a href="http://www.skysql.com/services/training/courses">training options</a>:</div>
<div>
<ul>
<li>
			Administering a MySQL Database</li>
<li>
			Administering MySQL Cluster</li>
<li>
			Developing Applications with the MySQL Database</li>
<li>
			High Availability for the MySQL Database</li>
<li>
			Performance Tuning for the MySQL Database</li>
</ul>
</div>
<div>
	You are of course always welcome to <a href="http://www.skysql.com/how-to-buy">request courses in new locations</a> and we will be happy to set these up for you. Onsite courses are also available, wherever you are.&nbsp;</div>
<div>
	&nbsp;</div>
<div>
	While setting up these new training dates, we have also been working on an overhaul of all our courses with updates to include new versions and in some cases new products. More details about these changes will follow soon in a separate blog entry.</div>
<div>
	&nbsp;</div>
<div>
	In the meantime, you can check out our new training calendar:&nbsp;<a href="http://www.skysql.com/services/training/schedule">http://www.skysql.com/services/training/schedule</a></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33185&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33185&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 11:19:21 +0000</pubDate>
    <dc:creator>SkySQL</dc:creator>
    <category>MariaDB</category>
    <category>MySQL</category>
    <category>SkySQL</category>
    <category>training</category>
  </item>

  <item>
    <title>State of PHPCR</title>
    <guid isPermaLink="false">http://pooteeweet.org/blog/0/2088</guid>
    <link>http://pooteeweet.org/blog/0/2088</link>
    <description>It feels like every minute a PHP developer somewhere on this planet starts implementing something aching to a CMS from scratch. Some do it because their project is &amp;quot;so big&amp;quot; it that it &amp;quot;obviously needs&amp;quot; a custom solution. Some do it because their project is &amp;quot;so small&amp;quot; it &amp;quot;obviously needs&amp;quot; just a few days of hacking .. to build a custom solution. Let me briefly focus on the later group. Working in a company with less than 10 people building websites for customers a project needs a bit of a CMS to manage those 10 &amp;quot;semi static&amp;quot; pages seems to be the poster child example of this group. The devs whip up a DB table, slap an ORM in front, maybe even use some generator for the admin UI. Done. Later the clients also wants versioning and luckily many ORMs provide some solution for that. Easy. Permissions? Most frameworks provide some ACL system. Child pages? ORM has some tree algorithm supported. Fulltext search? Integrate ElasticSearch. Custom page types? Uhm well by now you have enough sunken costs that you will make that happen somehow too. Some morning you wake up and you have created the next Drupal or Typo3. If you did, then it would be hard to claim that you did it wrong because both are very successful projects. What PHPCR aims to be is to provide you with a short cut for this path. Or in other words there should be a PHPCR implementation that is so easy to use, with so many helpful higher level components in your favorite framework, that it becomes the natural choice for your next CMS needing project.

Every time anyone talks about PHPCR, they will mention Jackrabbit sooner or later as it is the basis for the currently most mature PHPCR implementation. Here, I just did it too. Jackrabbit requires Java. More importantly it is not trivial and most of you have never heard about it, let alone used it. I think for many high scale use cases its great that PHPCR has been integrated with Jackrabbit, but it needs to be relegated to a side note you mention when someone starts talking about scaling to millions of documents and many GBs of data. Once there is a PHPCR implementation that works with pure PHP, using any RDBMS (including SQLite which is bundled with PHP) it will become easier to just use that instead of whipping up your own tables. No more convincing the sys-admin guy about adding a new daemon to the setup. Instead being able to tell the client what other features they could get in the next code sprint.

So today, we are not there yet. We have an implementation of PHPCR that works on top of Doctrine DBAL to in theory support any RDBMS. Well in reality it already does though the search API only works with MySQL and PostgreSQL. It also doesn't support versioning and ACLs. Oh and if you drop more than 50 documents into it, search performance will start to hurt quickly. Bummer. But there is good news too. The core infrastructure is laid out thanks to Benjamin. Progress on it, while not rocket fast, is continuous thanks to Liip intern Adrien .. as a matter of fact if you go to our demo page it would run all but the admin interface on top of it just fine (yes this includes the cool inline editing!).

I believe that a decently experienced database developer would need a man month to fix up the searching to perform decently unto lets say 1k documents as well as implement simple versioning on top of SQLite. Another 2 man months should enable implementing permissions and support for even more documents, ACLs and a few other goodies. Is this something that a 10 developer company can commit to when offering that simple CMS solution to one of their customers? Obviously not. This takes a few developers who are willing to invest into the future. Until they come along unfortunately PHPCR will continue to not be a viable option for many small CMS projects.

Update: In this post I failed to mention that there is also already a pretty solid implementation of PHPCR written in C by the Midgard team. However just as a Java solution can't be our pitch, I believe that a custom extension cannot either.</description>
    <content:encoded><![CDATA[<p>It feels like every minute a PHP developer somewhere on this planet starts implementing something aching to a CMS from scratch. Some do it because their project is &quot;so big&quot; it that it &quot;obviously needs&quot; a custom solution. Some do it because their project is &quot;so small&quot; it &quot;obviously needs&quot; just a few days of hacking .. to build a custom solution. Let me briefly focus on the later group. Working in a company with less than 10 people building websites for customers a project needs a bit of a CMS to manage those 10 &quot;semi static&quot; pages seems to be the poster child example of this group. The devs whip up a DB table, slap an ORM in front, maybe even use some generator for the admin UI. Done. Later the clients also wants versioning and luckily many ORMs provide some solution for that. Easy. Permissions? Most frameworks provide some ACL system. Child pages? ORM has some tree algorithm supported. Fulltext search? Integrate ElasticSearch. Custom page types? Uhm well by now you have enough sunken costs that you will make that happen somehow too. Some morning you wake up and you have created the next Drupal or Typo3. If you did, then it would be hard to claim that you did it wrong because both are very successful projects. What <a href="http://phpcr.github.com">PHPCR</a> aims to be is to provide you with a short cut for this path. Or in other words there should be a PHPCR implementation that is so easy to use, with so many helpful higher level components in your favorite framework, that it becomes the natural choice for your next CMS needing project.</p>

<p>Every time anyone talks about PHPCR, they will mention <a href="http://jackrabbit.apache.org">Jackrabbit</a> sooner or later as it is the basis for the currently most mature PHPCR <a href="http://github.com/jackalope/jackalope-jackrabbit">implementation</a>. Here, I just did it too. Jackrabbit requires Java. More importantly it is not trivial and most of you have never heard about it, let alone used it. I think for many high scale use cases its great that PHPCR has been integrated with Jackrabbit, but it needs to be relegated to a side note you mention when someone starts talking about scaling to millions of documents and many GBs of data. Once there is a PHPCR implementation that works with pure PHP, using any RDBMS (including SQLite which is bundled with PHP) it will become easier to just use that instead of whipping up your own tables. No more convincing the sys-admin guy about adding a new daemon to the setup. Instead being able to tell the client what other features they could get in the next code sprint.</p>

<p>So today, we are not there yet. We have an implementation of PHPCR that works on top of <a href="http://github.com/jackalope/jackalope-doctrine-dbal">Doctrine DBAL</a> to in theory support any RDBMS. Well in reality it already does though the search API only works with MySQL and PostgreSQL. It also doesn't support versioning and ACLs. Oh and if you drop more than 50 documents into it, search performance will start to hurt quickly. Bummer. But there is good news too. The core infrastructure is laid out thanks to Benjamin. Progress on it, while not rocket fast, is continuous thanks to Liip intern Adrien .. as a matter of fact if you go to our <a href="http://cmf.liip.ch">demo page</a> it would run all but the admin interface on top of it just fine (yes this includes the cool inline editing!).</p>

<p>I believe that a decently experienced database developer would need a man month to fix up the searching to perform decently unto lets say 1k documents as well as implement simple versioning on top of SQLite. Another 2 man months should enable implementing permissions and support for even more documents, ACLs and a few other goodies. Is this something that a 10 developer company can commit to when offering that simple CMS solution to one of their customers? Obviously not. This takes a few developers who are willing to invest into the future. Until they come along unfortunately PHPCR will continue to not be a viable option for many small CMS projects.</p>

<p><strong>Update</strong>: In this post I failed to mention that there is also already a pretty solid implementation of <a href="https://github.com/midgardproject/phpcr-midgard2">PHPCR written in C</a> by the Midgard team. However just as a Java solution can't be our pitch, I believe that a custom extension cannot either.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33184&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33184&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 10:45:28 +0000</pubDate>
    <dc:creator>Lukas Smith</dc:creator>
    <category>general</category>
  </item>

  <item>
    <title>Upcoming webinar: MySQL 5.6 Replication – For Next Generation of Web and Cloud Services</title>
    <guid isPermaLink="false">http://www.clusterdb.com/?p=2286</guid>
    <link>http://www.clusterdb.com/mysql-replication/upcoming-webinar-mysql-5-6-replication-for-next-generation-of-web-and-cloud-services/?utm_source=rss&amp;amp;utm_medium=rss&amp;amp;utm_campaign=upcoming-webinar-mysql-5-6-replication-for-next-generation-of-web-and-cloud</link>
    <description>MySQL 5.6 Replication - Global Transaction IDs
On Wednesday (16th May 2012), Mat Keep and I will be presenting the new replication features that are previewed as part of the latest MySQL 5.6 Development Release. If you&amp;#8217;d like to attend then register here.
MySQL 5.6 delivers new replication capabilities which we will discuss in the webinar:

High performance with Multi-Threaded Slaves and Optimized Row Based Replication
High availability with Global Transaction Identifiers, Failover Utilities and Crash Safe Slaves &amp;amp; Binlog
Data integrity with Replication Event Checksums
Dev/Ops agility with new Replication Utilities, Time Delayed Replication and more

The session will wrap up with resources to get started with MySQL 5.6 and an opportunity to ask questions.
The webinar will last 45-60 minutes and will start on Wednesday, May 16, 2012 at 09:00 Pacific time (America); start times in other time zones:

Wed, May 16: 06:00 Hawaii time
Wed, May 16: 10:00 Mountain time (America)
Wed, May 16: 11:00 Central time (America)
Wed, May 16: 12:00 Eastern time (America)
Wed, May 16: 16:00 UTC
Wed, May 16: 17:00 Western European time
Wed, May 16: 18:00 Central European time
Wed, May 16: 19:00 Eastern European time

As always, it&amp;#8217;s worth registering even if you can&amp;#8217;t make the live webcast as you&amp;#8217;ll  be emailed a link to the replay as soon as it&amp;#8217;s available.</description>
    <content:encoded><![CDATA[<div><a href="http://www.clusterdb.com/wp-content/uploads/2012/05/Global_Transaction_IDs.png"><img class="size-medium wp-image-2288" title="MySQL 5.6 Replication - Global Transaction IDs" src="http://www.clusterdb.com/wp-content/uploads/2012/05/Global_Transaction_IDs-300x186.png" alt="MySQL 5.6 Replication - Global Transaction IDs" width="300" height="186" /></a><p>MySQL 5.6 Replication - Global Transaction IDs</p></div>
<p>On Wednesday (16th May 2012), Mat Keep and I will be presenting the new replication features that are previewed as part of the latest MySQL 5.6 Development Release. If you&#8217;d like to attend then <a title="MySQL 5.6 Replication - For Next Generation of Web and Cloud Services" href="http://mysql.com/news-and-events/web-seminars/display-711.html" target="_blank">register here</a>.</p>
<p>MySQL 5.6 delivers new replication capabilities which we will discuss in the webinar:</p>
<ul>
<li>High performance with Multi-Threaded Slaves and Optimized Row Based Replication</li>
<li>High availability with Global Transaction Identifiers, Failover Utilities and Crash Safe Slaves &amp; Binlog</li>
<li>Data integrity with Replication Event Checksums</li>
<li>Dev/Ops agility with new Replication Utilities, Time Delayed Replication and more</li>
</ul>
<p>The session will wrap up with resources to get started with MySQL 5.6 and an opportunity to ask questions.</p>
<p>The webinar will last 45-60 minutes and will start on Wednesday, May 16, 2012 at 09:00 Pacific time (America); start times in other time zones:</p>
<ul>
<li>Wed, May 16: 06:00 Hawaii time</li>
<li>Wed, May 16: 10:00 Mountain time (America)</li>
<li>Wed, May 16: 11:00 Central time (America)</li>
<li>Wed, May 16: 12:00 Eastern time (America)</li>
<li>Wed, May 16: 16:00 UTC</li>
<li>Wed, May 16: 17:00 Western European time</li>
<li>Wed, May 16: 18:00 Central European time</li>
<li>Wed, May 16: 19:00 Eastern European time</li>
</ul>
<p>As always, it&#8217;s worth registering even if you can&#8217;t make the live webcast as you&#8217;ll  be emailed a link to the replay as soon as it&#8217;s available.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33182&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33182&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 08:40:12 +0000</pubDate>
    <dc:creator>Andrew Morgan</dc:creator>
    <category>MySQL Replication</category>
    <category>HA</category>
    <category>High Availability</category>
    <category>MySQL</category>
    <category>MySQL 5.6</category>
    <category>webinar</category>
  </item>

  <item>
    <title>Value or Reference?</title>
    <guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=5871</guid>
    <link>http://blog.mclaughlinsoftware.com/2012/05/10/value-or-reference/</link>
    <description>In class today, we reviewed pass-by-value (IN-only mode) parameters and pass-by-reference (INOUT and OUT mode) parameters for stored procedures. The analogy that finally seemed to hit home for the students was linking the modes to the story of Alice in Wonderland.
Here&amp;#8217;s the analogy and below is the code to support it:
&amp;#8220;A pass-by-value parameter in a procedure is like sending an immutable copy of Alice into the rabbit hole, which means she can&amp;#8217;t shrink, grow, or learn throughout the story; whereas, a pass-by-reference parameter in a procedure is like sending Alice into the rabbit hole where she can shrink, grow, fight the Jabberwocky, and learn things that make her life better when she exits the rabbit hole &amp;#8211; consistent with the storyline of Alice&amp;#8217;s revisit to Wonderland.&amp;#8221;
The example code creates a stored procedure that accepts two parameters &amp;#8211; one pass-by-value and one pass-by-reference. Inside the procedure there&amp;#8217;s a local variable and a reassignment of value to the pass-by-reference parameter. It&amp;#8217;s in this wonderland procedure (by the way don&amp;#8217;t forget to manage the DELIMITER value when you test it):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
CREATE PROCEDURE wonderland
&amp;#40; IN     pv_value_param  VARCHAR&amp;#40;20&amp;#41;
, INOUT  pv_ref_param    VARCHAR&amp;#40;20&amp;#41;&amp;#41;
BEGIN
&amp;nbsp;
  /* Declare a variable. */
  DECLARE lv_value_param  VARCHAR&amp;#40;20&amp;#41;;
&amp;nbsp;
  /* Query the local variable and reference parameter before changing values. */ 
  SELECT   'On Entry' AS &amp;quot;Where&amp;quot;
  ,        pv_value_param AS &amp;quot;Value Parameter&amp;quot;
  ,        pv_ref_param AS &amp;quot;Reference Parameter&amp;quot;
  ,        IFNULL&amp;#40;lv_value_param,'     '&amp;#41; AS &amp;quot;Local Variable&amp;quot;;
&amp;nbsp;
  /* Assign a lowercase value parameter to a local variable. */
  SET lv_value_param := LOWER&amp;#40;pv_value_param&amp;#41;;  
&amp;nbsp;
  /* Assign a uppercase reference parameter value to the reference parameter. */
  SET pv_ref_param := UPPER&amp;#40;pv_ref_param&amp;#41;;
&amp;nbsp;
  /* Query the local variable and reference parameter after changing values. */ 
  SELECT   'On Exit ' AS &amp;quot;Where&amp;quot;
  ,        pv_value_param AS &amp;quot;Value Parameter&amp;quot;
  ,        pv_ref_param AS &amp;quot;Reference Parameter&amp;quot;
  ,        IFNULL&amp;#40;lv_value_param,'     '&amp;#41; AS &amp;quot;Local Variable&amp;quot;;
&amp;nbsp;
END;
$$

A tester procedure than tests how the pass-by-value and pass-by-reference modes of operation differ. It&amp;#8217;s here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CREATE PROCEDURE tester
&amp;#40; IN  pv_value_param  VARCHAR&amp;#40;20&amp;#41;
, IN  pv_ref_param    VARCHAR&amp;#40;20&amp;#41;&amp;#41;
BEGIN
&amp;nbsp;
  /* Query the local and reference parameters. */ 
  SELECT   'Before  ' AS &amp;quot;Where&amp;quot;
  ,        pv_value_param AS &amp;quot;Value Parameter&amp;quot;
  ,        pv_ref_param AS &amp;quot;Reference Parameter&amp;quot;;
&amp;nbsp;
  /* Call the wonderland procedure that changes the pass-by-reference parameter. */
  CALL wonderland&amp;#40;pv_value_param, pv_ref_param&amp;#41;;
&amp;nbsp;
  /* Query the local and reference parameters. */ 
  SELECT   'After   ' AS &amp;quot;Where&amp;quot;
  ,        pv_value_param AS &amp;quot;Value Parameter&amp;quot;
  ,        pv_ref_param AS &amp;quot;Reference Parameter&amp;quot;;
&amp;nbsp;
END;
$$

You call the tester program with this syntax:

CALL tester&amp;#40;'Alice','Alice'&amp;#41;;

The test case returns the following values:

+----------+-----------------+---------------------+
| Where    | Value Parameter | Reference Parameter |
+----------+-----------------+---------------------+
| Before   | Alice           | Alice               |
+----------+-----------------+---------------------+
1 row in set (0.00 sec)
&amp;nbsp;
+----------+-----------------+---------------------+----------------+
| Where    | Value Parameter | Reference Parameter | Local Variable |
+----------+-----------------+---------------------+----------------+
| On Entry | Alice           | Alice               |                |
+----------+-----------------+---------------------+----------------+
1 row in set (0.02 sec)
&amp;nbsp;
+----------+-----------------+---------------------+----------------+
| Where    | Value Parameter | Reference Parameter | Local Variable |
+----------+-----------------+---------------------+----------------+
| On Exit  | Alice           | ALICE               | alice          |
+----------+-----------------+---------------------+----------------+
1 row in set (0.02 sec)
&amp;nbsp;
+----------+-----------------+---------------------+
| Where    | Value Parameter | Reference Parameter |
+----------+-----------------+---------------------+
| After    | Alice           | ALICE               |
+----------+-----------------+---------------------+
1 row in set (0.03 sec)

Basically, Alice inside the pv_ref_param parameter grows to uppercase during the trip through the wonderland procedure, while Alice inside the pv_value_param remains unchanged. If it didn&amp;#8217;t help you learn a principle, maybe it gave you a laugh on how to view the travels of IN-only and INOUT parameters.   
NOTE:Line 12 in the alice procedure is impossible with an immutable variable because the value of a call parameter to an immutable IN-only formal parameter shouldn&amp;#8217;t allow the call parameter value to change during the execution of the program. This means that MySQL IN-only mode parameter values actually hold a mutable copy of the call parameter and the call parameter can be either a variable or literal value. This is more easily demonstrated with this assignment procedure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE PROCEDURE assignment
&amp;#40; IN  pv_value_param  VARCHAR&amp;#40;20&amp;#41;&amp;#41;
BEGIN
&amp;nbsp;
  /* Query the local and reference parameters. */ 
  SELECT   'Before  ' AS &amp;quot;Where&amp;quot;
  ,        pv_value_param AS &amp;quot;Value Parameter&amp;quot;;
&amp;nbsp;
  /* Call the wonderland procedure that changes the pass-by-reference parameter. */
  SET pv_value_param := UPPER&amp;#40;pv_value_param&amp;#41;;
&amp;nbsp;
  /* Query the local and reference parameters. */ 
  SELECT   'After   ' AS &amp;quot;Where&amp;quot;
  ,        pv_value_param AS &amp;quot;Value Parameter&amp;quot;;
&amp;nbsp;
END;
$$

Therefore a call like this prints an uppercase INBOUND string inside the program but can return nothing to the calling scope since the call parameter is a string literal.

1
CALL assignment&amp;#40;'inbound'&amp;#41;;</description>
    <content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/B001HN694K/ref=as_li_tf_il?ie=UTF8&amp;tag=macloc-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B001HN694K"><img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;Format=_SL110_&amp;ASIN=B001HN694K&amp;MarketPlace=US&amp;ID=AsinImage&amp;WS=1&amp;tag=macloc-20&amp;ServiceVersion=20070822" /></a>In class today, we reviewed pass-by-value (<code>IN</code>-only mode) parameters and pass-by-reference (<code>INOUT</code> and <code>OUT</code> mode) parameters for stored procedures. The analogy that finally seemed to hit home for the students was linking the modes to the story of Alice in Wonderland.</p>
<p>Here&#8217;s the analogy and below is the code to support it:</p>
<p><span><em>&#8220;A pass-by-value parameter in a procedure is like sending an immutable copy of Alice into the rabbit hole, which means she can&#8217;t shrink, grow, or learn throughout the story; whereas, a pass-by-reference parameter in a procedure is like sending Alice into the rabbit hole where she can shrink, grow, fight the Jabberwocky, and learn things that make her life better when she exits the rabbit hole &#8211; consistent with the storyline of Alice&#8217;s revisit to Wonderland.&#8221;</em></span></p>
<p>The example code creates a stored procedure that accepts two parameters &#8211; one pass-by-value and one pass-by-reference. Inside the procedure there&#8217;s a local variable and a reassignment of value to the pass-by-reference parameter. It&#8217;s in this <code>wonderland</code> procedure (by the way don&#8217;t forget to manage the <code>DELIMITER</code> value when you test it):</p>

<div><table><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td><pre><span>CREATE</span> <span>PROCEDURE</span> wonderland
<span>&#40;</span> <span>IN</span>     pv_value_param  <span>VARCHAR</span><span>&#40;</span><span>20</span><span>&#41;</span>
<span>,</span> <span>INOUT</span>  pv_ref_param    <span>VARCHAR</span><span>&#40;</span><span>20</span><span>&#41;</span><span>&#41;</span>
<span>BEGIN</span>
&nbsp;
  <span>/* Declare a variable. */</span>
  <span>DECLARE</span> lv_value_param  <span>VARCHAR</span><span>&#40;</span><span>20</span><span>&#41;</span>;
&nbsp;
  <span>/* Query the local variable and reference parameter before changing values. */</span> 
  <span>SELECT</span>   <span>'On Entry'</span> <span>AS</span> <span>&quot;Where&quot;</span>
  <span>,</span>        pv_value_param <span>AS</span> <span>&quot;Value Parameter&quot;</span>
  <span>,</span>        pv_ref_param <span>AS</span> <span>&quot;Reference Parameter&quot;</span>
  <span>,</span>        IFNULL<span>&#40;</span>lv_value_param<span>,</span><span>'     '</span><span>&#41;</span> <span>AS</span> <span>&quot;Local Variable&quot;</span>;
&nbsp;
  <span>/* Assign a lowercase value parameter to a local variable. */</span>
  <span>SET</span> lv_value_param :<span>=</span> <span>LOWER</span><span>&#40;</span>pv_value_param<span>&#41;</span>;  
&nbsp;
  <span>/* Assign a uppercase reference parameter value to the reference parameter. */</span>
  <span>SET</span> pv_ref_param :<span>=</span> <span>UPPER</span><span>&#40;</span>pv_ref_param<span>&#41;</span>;
&nbsp;
  <span>/* Query the local variable and reference parameter after changing values. */</span> 
  <span>SELECT</span>   <span>'On Exit '</span> <span>AS</span> <span>&quot;Where&quot;</span>
  <span>,</span>        pv_value_param <span>AS</span> <span>&quot;Value Parameter&quot;</span>
  <span>,</span>        pv_ref_param <span>AS</span> <span>&quot;Reference Parameter&quot;</span>
  <span>,</span>        IFNULL<span>&#40;</span>lv_value_param<span>,</span><span>'     '</span><span>&#41;</span> <span>AS</span> <span>&quot;Local Variable&quot;</span>;
&nbsp;
<span>END</span>;
$$</pre></td></tr></table></div>

<p>A <code>tester</code> procedure than tests how the pass-by-value and pass-by-reference modes of operation differ. It&#8217;s here:</p>

<div><table><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td><pre><span>CREATE</span> <span>PROCEDURE</span> tester
<span>&#40;</span> <span>IN</span>  pv_value_param  <span>VARCHAR</span><span>&#40;</span><span>20</span><span>&#41;</span>
<span>,</span> <span>IN</span>  pv_ref_param    <span>VARCHAR</span><span>&#40;</span><span>20</span><span>&#41;</span><span>&#41;</span>
<span>BEGIN</span>
&nbsp;
  <span>/* Query the local and reference parameters. */</span> 
  <span>SELECT</span>   <span>'Before  '</span> <span>AS</span> <span>&quot;Where&quot;</span>
  <span>,</span>        pv_value_param <span>AS</span> <span>&quot;Value Parameter&quot;</span>
  <span>,</span>        pv_ref_param <span>AS</span> <span>&quot;Reference Parameter&quot;</span>;
&nbsp;
  <span>/* Call the wonderland procedure that changes the pass-by-reference parameter. */</span>
  <span>CALL</span> wonderland<span>&#40;</span>pv_value_param<span>,</span> pv_ref_param<span>&#41;</span>;
&nbsp;
  <span>/* Query the local and reference parameters. */</span> 
  <span>SELECT</span>   <span>'After   '</span> <span>AS</span> <span>&quot;Where&quot;</span>
  <span>,</span>        pv_value_param <span>AS</span> <span>&quot;Value Parameter&quot;</span>
  <span>,</span>        pv_ref_param <span>AS</span> <span>&quot;Reference Parameter&quot;</span>;
&nbsp;
<span>END</span>;
$$</pre></td></tr></table></div>

<p>You call the <code>tester</code> program with this syntax:</p>

<div><div><pre><span>CALL</span> tester<span>&#40;</span><span>'Alice'</span><span>,</span><span>'Alice'</span><span>&#41;</span>;</pre></div></div>

<p>The test case returns the following values:</p>

<div><div><pre>+----------+-----------------+---------------------+
| Where    | Value Parameter | Reference Parameter |
+----------+-----------------+---------------------+
| Before   | Alice           | Alice               |
+----------+-----------------+---------------------+
1 row in set (0.00 sec)
&nbsp;
+----------+-----------------+---------------------+----------------+
| Where    | Value Parameter | Reference Parameter | Local Variable |
+----------+-----------------+---------------------+----------------+
| On Entry | Alice           | Alice               |                |
+----------+-----------------+---------------------+----------------+
1 row in set (0.02 sec)
&nbsp;
+----------+-----------------+---------------------+----------------+
| Where    | Value Parameter | Reference Parameter | Local Variable |
+----------+-----------------+---------------------+----------------+
| On Exit  | Alice           | ALICE               | alice          |
+----------+-----------------+---------------------+----------------+
1 row in set (0.02 sec)
&nbsp;
+----------+-----------------+---------------------+
| Where    | Value Parameter | Reference Parameter |
+----------+-----------------+---------------------+
| After    | Alice           | ALICE               |
+----------+-----------------+---------------------+
1 row in set (0.03 sec)</pre></div></div>

<p>Basically, Alice inside the <code>pv_ref_param</code> parameter grows to uppercase during the trip through the <code>wonderland</code> procedure, while Alice inside the <code>pv_value_param</code> remains unchanged. If it didn&#8217;t help you learn a principle, maybe it gave you a laugh on how to view the travels of <code>IN</code>-only and <code>INOUT</code> parameters. <img src="http://blog.mclaughlinsoftware.com/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley" />  </p>
<p><strong>NOTE:</strong>Line 12 in the <code>alice</code> procedure is impossible with an immutable variable because the value of a call parameter to an immutable <code>IN</code>-only formal parameter shouldn&#8217;t allow the call parameter value to change during the execution of the program. This means that MySQL <code>IN</code>-only mode parameter values actually hold a mutable copy of the call parameter and the call parameter can be either a variable or literal value. This is more easily demonstrated with this <code>assignment</code> procedure:</p>

<div><table><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td><pre><span>CREATE</span> <span>PROCEDURE</span> assignment
<span>&#40;</span> <span>IN</span>  pv_value_param  <span>VARCHAR</span><span>&#40;</span><span>20</span><span>&#41;</span><span>&#41;</span>
<span>BEGIN</span>
&nbsp;
  <span>/* Query the local and reference parameters. */</span> 
  <span>SELECT</span>   <span>'Before  '</span> <span>AS</span> <span>&quot;Where&quot;</span>
  <span>,</span>        pv_value_param <span>AS</span> <span>&quot;Value Parameter&quot;</span>;
&nbsp;
  <span>/* Call the wonderland procedure that changes the pass-by-reference parameter. */</span>
  <span>SET</span> pv_value_param :<span>=</span> <span>UPPER</span><span>&#40;</span>pv_value_param<span>&#41;</span>;
&nbsp;
  <span>/* Query the local and reference parameters. */</span> 
  <span>SELECT</span>   <span>'After   '</span> <span>AS</span> <span>&quot;Where&quot;</span>
  <span>,</span>        pv_value_param <span>AS</span> <span>&quot;Value Parameter&quot;</span>;
&nbsp;
<span>END</span>;
$$</pre></td></tr></table></div>

<p>Therefore a call like this prints an uppercase <code>INBOUND</code> string inside the program but can return nothing to the calling scope since the call parameter is a string literal.</p>

<div><table><tr><td><pre>1
</pre></td><td><pre><span>CALL</span> assignment<span>&#40;</span><span>'inbound'</span><span>&#41;</span>;</pre></td></tr></table></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33181&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33181&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 07:48:05 +0000</pubDate>
    <dc:creator>Michael McLaughlin</dc:creator>
    <category>MySQL</category>
    <category>SQL/PSM</category>
    <category>Stored Procedures</category>
  </item>

  <item>
    <title>Database Workbench 4.2.4 released</title>
    <guid isPermaLink="false">3449B4A1-BA24-46B5-9FFD-3BD0378A11D8</guid>
    <link>http://www.upscene.com/displaynews.php?item=20120510</link>
    <description>Database workbench 4.2.4 released! 

[2012-05-10]
The latest version of Database Workbench brings you new enhancements and bugfixes over the 4.2 release.

Database Workbench is a database development tool that works natively with:
* Oracle
* MS SQL Server
* MySQL
* Firebird
* InterBase
* SQL Anywhere

More information on Database Workbench can be found here, the full list of changes is available from our tracker here.</description>
    <content:encoded><![CDATA[<b>Database workbench 4.2.4 released! </b><br />
<br />
[2012-05-10]<br />
The latest version of Database Workbench brings you new enhancements and bugfixes over the 4.2 release.<br />
<br />
Database Workbench is a database development tool that works natively with:<br />
* Oracle<br />
* MS SQL Server<br />
* MySQL<br />
* Firebird<br />
* InterBase<br />
* SQL Anywhere<br />
<br />
More information on Database Workbench can be found <a href="http://www.upscene.com/go/?go=dbw">here</a>, the full list of changes is available from <a href="http://www.upscene.com/go/?go=tracker&amp;v=4.2.4&amp;id=3" target="_blank">our tracker here</a>.<br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33194&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33194&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 07:25:36 +0000</pubDate>
    <dc:creator>Martijn Tonies</dc:creator>
  </item>

  <item>
    <title>New distribution of random generator for sysbench – Zipf</title>
    <guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=9439</guid>
    <link>http://www.mysqlperformanceblog.com/2012/05/09/new-distribution-of-random-generator-for-sysbench-zipf/</link>
    <description>Sysbench has three distribution for random numbers: uniform, special and gaussian. I mostly use uniform and special, and I feel that both do not fully reflect my needs when I run benchmarks. Uniform is stupidly simple: for a table with 1 mln rows, each row gets equal amount of hits. This barely reflects real system, it also does not allow effectively test caching solution, each row can be equally put into cache or removed. That&amp;#8217;s why there is special distribution, which is better, but to other extreme &amp;#8211; it is skewed to very small percentage of rows, which makes this distribution good to test cache, but it is hard to emulate high IO load.

That&amp;#8217;s why I was looking for alternatives, and Zipfian distribution seems decent one. This distribution has a parameter θ (theta), which defines how skewed the distribution is. A physical sense of this parameter, if to apply to database tables, is following: say row 1 accessed N, then row 2 is accessed 2^θ less times, row 3 is accessed 3^θ less, &amp;#8230;, row X is accessed X^θ less times.
Say θ=1.1, then if row 1 accessed 1,000,000 times, then row 2 is : 1,000,000/(2^1.1)=466,516 times, row 3: 1,000,000/(2^1.1)=298,652 times, &amp;#8230;, row id=10000 : 1,000,000/(10,000^1.1) = 39 times.
Obviously with θ=0 we are getting uniform distribution &amp;#8211; each row is accessed equal times ( for row X: 1/(X^0) ).
There is a research that shows that user behavior can be described by this distribution: Zipf, Power-laws, and Pareto &amp;#8211; a ranking tutorial
To see distribution on graphs, I took tables with 1mln rows and run row lookup 1 million times.
There are histograms on how many times each row selected for different θ: 0.5, 0.9, 1.1:

The curve is very skewed, so I zoomed graphs to show only 0-100k level:

I implemented Zipf for sysbench, right now it is in a separate tree https://code.launchpad.net/~vadim-tk/sysbench/zipf-distribution, you are welcome to try if it sounds interesting.
I am going to run couple incoming benchmarks with this distribution.
Follow @VadimTk
</description>
    <content:encoded><![CDATA[<p>Sysbench has three distribution for random numbers: uniform, special and gaussian. I mostly use uniform and special, and I feel that both do not fully reflect my needs when I run benchmarks. Uniform is stupidly simple: for a table with 1 mln rows, each row gets equal amount of hits. This barely reflects real system, it also does not allow effectively test caching solution, each row can be equally put into cache or removed. That&#8217;s why there is special distribution, which is better, but to other extreme &#8211; it is skewed to very small percentage of rows, which makes this distribution good to test cache, but it is hard to emulate high IO load.<br />
<span></span><br />
That&#8217;s why I was looking for alternatives, and <a href="http://en.wikipedia.org/wiki/Zipf's_law">Zipfian distribution</a> seems decent one. This distribution has a parameter θ (theta), which defines how skewed the distribution is. A physical sense of this parameter, if to apply to database tables, is following: say row 1 accessed N, then row 2 is accessed 2^θ less times, row 3 is accessed 3^θ less, &#8230;, row X is accessed X^θ less times.<br />
Say θ=1.1, then if row 1 accessed 1,000,000 times, then row 2 is : 1,000,000/(2^1.1)=466,516 times, row 3: 1,000,000/(2^1.1)=298,652 times, &#8230;, row id=10000 : 1,000,000/(10,000^1.1) = 39 times.</p>
<p>Obviously with θ=0 we are getting uniform distribution &#8211; each row is accessed equal times ( for row X: 1/(X^0) ).</p>
<p>There is a research that shows that user behavior can be described by this distribution: <a href="http://www.hpl.hp.com/research/idl/papers/ranking/ranking.html">Zipf, Power-laws, and Pareto &#8211; a ranking tutorial</a></p>
<p>To see distribution on graphs, I took tables with 1mln rows and run row lookup 1 million times.</p>
<p>There are histograms on how many times each row selected for different θ: 0.5, 0.9, 1.1:<br />
<a href="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/zipf.png"><img src="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/zipf.png" alt="" title="zipf" width="640" height="398" class="aligncenter size-full wp-image-9458" /></a></p>
<p>The curve is very skewed, so I zoomed graphs to show only 0-100k level:<br />
<a href="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/zipf-zoom.png"><img src="http://www.mysqlperformanceblog.com/wp-content/uploads/2012/05/zipf-zoom.png" alt="" title="zipf-zoom" width="640" height="398" class="aligncenter size-full wp-image-9459" /></a></p>
<p>I implemented Zipf for sysbench, right now it is in a separate tree https://code.launchpad.net/~vadim-tk/sysbench/zipf-distribution, you are welcome to try if it sounds interesting.</p>
<p>I am going to run couple incoming benchmarks with this distribution.</p>
<p><a href="https://twitter.com/VadimTk" data-show-count="false">Follow @VadimTk</a><br />
</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33178&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33178&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 00:50:28 +0000</pubDate>
    <dc:creator>MySQL Performance Blog</dc:creator>
    <category>Benchmarks</category>
    <category>MySQL</category>
  </item>

  <item>
    <title>Mixed signals in IT’s great war over IP</title>
    <guid isPermaLink="false">http://blogs.the451group.com/opensource/?p=5996</guid>
    <link>http://feedproxy.google.com/~r/451opensource/~3/fkwdDCsdVgE/</link>
    <description>Recent news that Microsoft and Barnes &amp;amp; Noble agreed to partner on the Nook e-reader line rather than keep fighting over intellectual property suggests the prospect of more settlement and fewer IP suits in the industry. However, the deal further obscures the blurry IP and patent landscape currently impacting both enterprise IT and consumer technology.
It is good to see settlement &amp;#8212; something I&amp;#8217;ve been calling for, while also warning against patent and IP aggression. However, this settlment comes from the one conflict in this ongoing war that was actually shedding some light on the matter, rather than further complicating it.
See the full article at TechNewsWorld.
</description>
    <content:encoded><![CDATA[<p>Recent news that Microsoft and Barnes &amp; Noble agreed to partner on the Nook e-reader line rather than keep fighting over intellectual property suggests the prospect of more settlement and fewer IP suits in the industry. However, the deal further obscures the blurry IP and patent landscape currently impacting both enterprise IT and consumer technology.</p>
<p>It is good to see settlement &#8212; something I&#8217;ve been calling for, while also warning against patent and IP aggression. However, this settlment comes from the one conflict in this ongoing war that was actually shedding some light on the matter, rather than further complicating it.</p>
<p>See the <a href="http://www.technewsworld.com/story/75051.html">full article</a> at TechNewsWorld.</p>
<img src="http://feeds.feedburner.com/~r/451opensource/~4/fkwdDCsdVgE" height="1" width="1" /><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33177&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33177&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Thu, 10 May 2012 00:05:30 +0000</pubDate>
    <dc:creator>The 451 Group</dc:creator>
    <category>Software</category>
    <category>451 Research</category>
    <category>APIs</category>
    <category>Apple</category>
    <category>asserted</category>
    <category>court</category>
    <category>decision</category>
    <category>google</category>
    <category>innovation</category>
    <category>intellectual property</category>
    <category>IP</category>
    <category>jay lyman</category>
    <category>lawsuits</category>
    <category>lawyers</category>
    <category>Linux</category>
    <category>market</category>
    <category>open source software</category>
    <category>open-source</category>
    <category>Oracle</category>
    <category>patents</category>
    <category>rights</category>
    <category>Samsung</category>
    <category>servers</category>
    <category>software patents</category>
    <category>The 451 Group</category>
    <category>troll</category>
    <category>Windows</category>
  </item>

  <item>
    <title>“WordPress on Amazon S3″, OblakSoft Cloud Storage Newsletter, May 2012</title>
    <guid isPermaLink="false">http://www.oblaksoft.com/?p=2521</guid>
    <link>http://www.oblaksoft.com/wordpress-on-s3-newsletter-may-2012/</link>
    <description>WordPress on S3: run a beautiful website on Amazon S3 cloud storage
OblakSoft is proud to introduce the 1st ever dynamic WordPress site running on top of Amazon S3: Yapixx.  Now you too can launch your own beautiful website on Amazon S3.
While Yapixx stands for Yet Another Picture Sharing Site, it is actually one of a kind.  Yapixx is WordPress that was moved to run on top of Amazon S3 storage without changing a line of code in the WordPress core engine.




What is Yapixx?
Try out Yapixx
Take your WordPress to S3





What is Yapixx?
Yapixx is ready-to-run WordPress on Amazon S3.  It took about one man-week to create Yapixx, thanks to power of WordPress.  WordPress is a mature and versatile platform that powers millions of websites with diverse purposes from blogging to social networking.  There are thousands of plugins and themes written for WordPress that can transform the website into pretty much anything.  And now it can run with Amazon S3 without writing a line of code.
Yapixx taps into power of Amazon S3.  Amazon S3 is inexpensive, highly reliable, available and scalable storage service.  It got even less expensive recently and its usage is growing 2.5-2.9 times year-over-year.  Using Amazon S3 to store Yapixx data has the following benefits:

Storage cost scales with usage, no upfront reservation is needed
Storage consumption scales up and down with the amount of data stored
Storage is extremely reliable and durable by Amazon S3 design
Pictures are served by Amazon S3 directly, which makes Yapixx highly scalable
No database backup and recovery is needed, now that Amazon S3 holds both for the website content stored in WordPress database and website’s media files

Yapixx demonstrates how easy it is to create web applications on top of Amazon S3.  Amazon S3 has been able to only power static websites; now S3 can power sophisticated dynamic web software such as WordPress.

Try out Yapixx
Here are the five easy steps to get Yapixx up and running:

Sign up for an AWS account.
Create an S3 bucket.
Start EC2 instance using Yapixx AMI.
Connect to the web application from a web browser.
Enter the S3 data location and authentication information.

The full step-by-step guide for launching Yapixx is available here.
All done!  You’ve got a picture sharing site running on top of Amazon S3.
 

Get started with Yapixx today for FREE!  It may be the boost that you need to propel your creative ideas and turn them into the next $1B acquisition.

Take your own WordPress site to Amazon S3
You can use Yapixx as a starting point to create your own beautiful WordPress site.  The plugins that turn WordPress into Yapixx, such as the WP2Cloud plugin, the Yapixx theme, etc. are available under the GPL completely FREE.  Creating a new AMI with your own web application is a matter of two mouse clicks in the AWS management console:


Moreover, you may even get your web application hosted completely free in the Amazon cloud, if your AWS usage doesn’t exceed the AWS free tier limits.  This is a great way to get a new web application to production quickly, absolutely FREE!  And when your web application usage grows, you can easily move it to larger cloud instance or to your own hardware: the data is stored in Amazon S3 and can be accessed from anywhere.


Launch your own WordPress site to the cloud today!  It’s easy and FREE, no writing code is required.  Start at http://www.oblaksoft.com/downloads.
Let us know what you think about Yapixx!  How can we further simplify the migration of websites to the cloud storage?
See also:
WordPress on S3: how it works.
WordPress on S3: the beauty of simplicity (blog).</description>
    <content:encoded><![CDATA[<h2>WordPress on S3: run a beautiful website on Amazon S3 cloud storage</h2>
<p>OblakSoft is proud to introduce the 1<sup>st</sup> ever dynamic <a href="http://wordpress.org/">WordPress</a> site running on top of <a href="http://aws.amazon.com/s3/">Amazon S3</a>: Yapixx.  Now you too can launch your own beautiful website on Amazon S3.</p>
<p>While Yapixx stands for <strong>Y</strong>et <strong>A</strong>nother <strong>Pic</strong>ture <strong>S</strong>haring <strong>S</strong>ite, it is actually one of a kind.  Yapixx is <a href="http://wordpress.org/">WordPress</a> that was moved to run on top of <a href="http://aws.amazon.com/s3/">Amazon S3</a> storage without changing a line of code in the WordPress core engine.</p>
<div>
<img class="wp-image-2541 alignleft" title="WordPress on S3 - Yapixx" src="http://www.oblaksoft.com/wp-content/uploads/2012/05/yapixx-logo.png" alt="" width="268" height="134" /></div>
<div>
<ul>
<li><a href="http://www.oblaksoft.com/wordpress-on-s3-newsletter-may-2012/#_what_is_yapixx">What is Yapixx?</a></li>
<li><a href="http://www.oblaksoft.com/wordpress-on-s3-newsletter-may-2012/#_try_out_yapixx">Try out Yapixx</a></li>
<li><a href="http://www.oblaksoft.com/wordpress-on-s3-newsletter-may-2012/#_your_site_on_s3">Take your WordPress to S3</a></li>
</ul>
</div>
<div></div>
<p><span></span><br />
<a name="_what_is_yapixx"></a></p>
<h2>What is Yapixx?</h2>
<p>Yapixx is ready-to-run WordPress on Amazon S3.  It took about one man-week to create Yapixx, thanks to power of WordPress.  WordPress is a mature and versatile platform that powers millions of websites with diverse purposes from blogging to social networking.  There are thousands of <a href="http://wordpress.org/extend/plugins/">plugins</a> and <a href="http://wordpress.org/extend/themes/">themes</a> written for WordPress that can transform the website into pretty much <a href="http://wordpress.org/showcase/">anything</a>.  <strong>And now it can run with Amazon S3 without writing a line of code.</strong></p>
<p>Yapixx taps into power of Amazon S3.  Amazon S3 is inexpensive, highly reliable, available and scalable storage service.  It got even <a href="http://aws.typepad.com/aws/2012/02/amazon-s3-price-reduction.html">less expensive</a> recently and its usage is growing <a href="http://aws.typepad.com/aws/2012/01/amazon-s3-growth-for-2011-now-762-billion-objects.html">2.5-2.9 times</a> year-over-year.  Using Amazon S3 to store Yapixx data has the following benefits:</p>
<ul>
<li>Storage cost scales with usage, no upfront reservation is needed</li>
<li>Storage consumption scales up and down with the amount of data stored</li>
<li>Storage is extremely reliable and durable by Amazon S3 design</li>
<li>Pictures are served by Amazon S3 directly, which makes Yapixx highly scalable</li>
<li>No database backup and recovery is needed, now that Amazon S3 holds both for the website content stored in WordPress database and website’s media files</li>
</ul>
<p>Yapixx demonstrates how easy it is to create web applications on top of Amazon S3.  Amazon S3 has been able to only power <a href="http://www.allthingsdistributed.com/2011/08/Jekyll-amazon-s3.html">static websites</a>; now S3 can power sophisticated dynamic web software such as WordPress.</p>
<p><a name="_try_out_yapixx"></a></p>
<h2>Try out Yapixx</h2>
<p>Here are the five easy steps to get Yapixx up and running:</p>
<ol>
<li><a href="http://docs.amazonwebservices.com/AmazonS3/latest/gsg/SigningUpforS3.html">Sign up</a> for an AWS account.</li>
<li><a href="http://docs.amazonwebservices.com/AmazonS3/latest/gsg/CreatingABucket.html">Create</a> an S3 bucket.</li>
<li>Start EC2 instance using <a href="http://www.oblaksoft.com/downloads/">Yapixx AMI</a>.</li>
<li>Connect to the web application from a web browser.</li>
<li>Enter the S3 data location and authentication information.</li>
</ol>
<p>The full step-by-step guide for launching Yapixx is available <a href="http://www.slideshare.net/artemlivshits/wordpress-on-s3-stepbystep">here</a>.</p>
<p>All done!  You’ve got a picture sharing site running on top of Amazon S3.</p>
<p> <a href="http://www.oblaksoft.com/wp-content/uploads/2012/05/yapixx-frontpage.png"><img class="aligncenter  wp-image-2547" title="WordPress on S3 - yapixx-frontpage" src="http://www.oblaksoft.com/wp-content/uploads/2012/05/yapixx-frontpage.png" alt="" width="676" height="580" /></a></p>
<div></div>
<p>Get started with Yapixx today for FREE!  It may be the boost that you need to propel your creative ideas and turn them into the next $1B acquisition.</p>
<p><a name="_your_site_on_s3"></a></p>
<h2>Take your own WordPress site to Amazon S3</h2>
<p>You can use Yapixx as a starting point to create your own beautiful WordPress site.  The plugins that turn WordPress into Yapixx, such as the WP2Cloud plugin, the Yapixx theme, etc. are available under the GPL completely FREE.  Creating a new AMI with your own web application is a matter of two mouse clicks in the AWS management console:</p>
<p><a href="http://www.oblaksoft.com/wp-content/uploads/2012/05/create-AMI.png"><img class="aligncenter size-full wp-image-2548" title="WordPress on S3 create-AMI" src="http://www.oblaksoft.com/wp-content/uploads/2012/05/create-AMI.png" alt="" width="371" height="158" /></a></p>
<div></div>
<p>Moreover, you may even get your web application hosted completely free in the Amazon cloud, if your AWS usage doesn’t exceed the <a href="http://aws.amazon.com/free/">AWS free tier</a> limits.  This is a great way to get a new web application to production quickly, absolutely FREE!  And when your web application usage grows, you can easily move it to larger cloud instance or to your own hardware: the data is stored in Amazon S3 and can be accessed from anywhere.</p>
<p><a href="http://www.oblaksoft.com/wp-content/uploads/2011/12/wp-cloud-logo.png"><img class="aligncenter size-full wp-image-2528" title="WordPress-Cloud-logo" src="http://www.oblaksoft.com/wp-content/uploads/2011/12/wp-cloud-logo.png" alt="WordPress on Cloud" width="297" height="149" /></a><br />
<br clear="ALL" /><br />
Launch your own WordPress site to the cloud today!  It’s easy and FREE, no writing code is required.  Start at <a href="http://www.oblaksoft.com/downloads">http://www.oblaksoft.com/downloads</a>.</p>
<p>Let us know what you think about Yapixx!  How can we further simplify the migration of websites to the cloud storage?</p>
<p><strong><em>See also:</em></strong></p>
<p>WordPress on S3: <a href="http://www.oblaksoft.com/wordpress-on-s3-how-it-works">how it works</a>.</p>
<p>WordPress on S3: <a href="http://www.oblaksoft.com/wordpress-on-s3-the-beauty-of-simplicity/" />the beauty of simplicity (blog)<a>.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33176&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33176&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 23:55:30 +0000</pubDate>
    <dc:creator>Artem Livshits</dc:creator>
    <category>OblakSoft Newsletter</category>
    <category>cloud</category>
    <category>MySQL</category>
    <category>performance</category>
    <category>reliability</category>
    <category>S3</category>
    <category>website</category>
    <category>Wordpress</category>
  </item>

  <item>
    <title>Case Study: Waiting Room Solutions Relies on MySQL for Web-Based Medical Management Systems</title>
    <guid isPermaLink="false">https://blogs.oracle.com/MySQL/entry/case_study_waiting_room_solutions</guid>
    <link>https://blogs.oracle.com/MySQL/entry/case_study_waiting_room_solutions</link>
    <description>Waiting Room
Solutions (WRS) is an award-winning web-based Electronic Medical Records (EMR)
and Practice Management System for physicians’ offices. Based in Goshen, NY, WRS
serves almost 3,000 users for their needs in charting, medical record filing,
payment tracking, prescription and reporting via the SaaS (Software as a
Service) model, and WRS has sent over 20,000 electronic prescriptions a month
over its secure network. 
  The Business Challenge 
  WRS was
looking for a robust database for enterprise-class web-based applications with
the following features: 
  1. Security 
  Medical records and health information are highly confidential, and WRS
expected to be fully incompliance with privacy regulations such as the HIPAA
Privacy Rule. 
  2. Data Integrity 
  It is important to minimize data corruption and inconsistency for medical
records, because they directly impact critical medical judgment and decisions. 
  3. Speed/Performance 
  Doctors work in a fast-paced environment and are not known for being
patient. WRS was looking for a database with high performance, and was aiming to
deliver the speed of an on-premise system with the SaaS model. 
  4. Low Cost and Scalability 
  WRS serves customers ranging from small practices to large enterprises. Therefore,
WRS needed a database solution that was affordable to the smallest healthcare
provider, while being able to scale to meet the demands of the largest
providers who have hundreds of facilities.   
  The MySQL Solution 
  WRS evaluated
both MySQL and PostgreSQL for its EMR and Practice Management System, and
decided to use MySQL for the following reasons: 
  1. Ubiquity 
  MySQL is the world’s most popular open-source database with millions of
installations. It is widely used and is a proven technology. 
  2. Better Support 
  In addition to the community users who actively share knowledge and best
practices, it was also important for WRS to know that there is an enterprise
behind the product that they can turn to for help if needed. MySQL was created
by MySQL AB, and subsequently was developed and improved by Sun Microsystems
and now Oracle through acquisitions.It provides WRS with Scalability. 
  3. Open Source / Open Standard 
  MySQL is the “M” in the open-source LAMP (Linux, Apache, MySQL and PHP/Python/Perl)
stack. By leveraging and integrating the existing open-source technology, WRS
was able to develop products and features more quickly, and with better
interoperability. 
  WRS uses
MySQL replication to achieve scalability, deploying the master-slave topology.
“With MySQL, we can scale as we need. I can install it on many machines and
handle any required volume,” said Brad Hall, Systems Administrator at WRS. “This
gives us far more flexibility with hardware.” Three primary slaves all have to
handle the volume of over 6,000 queries per second throughout the day, and WRS
uses partitioning to increase speed. 
  With MySQL,
WRS was able to develop a modular EMR and Practice Management solution to support
thousands of medical practices, with the following features: electronic medical
and health records; billing; scheduling; electronic prescriptions; online
patient registration; practice website; messaging; order tracking;
transcription; document management; and disease management. “We required an
open source solution that was well maintained, stable, and actively growing. In
addition, we required a solution that offered access to enterprise support when
needed. MySQL was the right choice for us,” said Hall. “The performance,
scalability, and reliability delivered by MySQL with InnoDB has been excellent.”  
  Learn more
about Waiting Room Solutions: http://www.waitingroomsolutions.com/ 
  Read more
MySQL customer stories: http://www.mysql.com/customers/ </description>
    <content:encoded><![CDATA[<p><span>Waiting Room
Solutions (WRS) is an award-winning web-based Electronic Medical Records (EMR)
and Practice Management System for physicians’ offices. Based in Goshen, NY, WRS
serves almost 3,000 users for their needs in charting, medical record filing,
payment tracking, prescription and reporting via the SaaS (Software as a
Service) model, and WRS has sent over 20,000 electronic prescriptions a month
over its secure network.</span></p> 
  <p><b>The Business Challenge</b></p> 
  <p><span>WRS was
looking for a robust database for enterprise-class web-based applications with
the following features:</span></p> 
  <p><b><span><span>1.<span> </span></span></span></b><b><span>Security</span></b></p> 
  <p><span>Medical records and health information are highly confidential, and WRS
expected to be fully incompliance with privacy regulations such as the HIPAA
Privacy Rule.</span></p> 
  <p><b><span><span>2.<span> </span></span></span></b><b><span>Data Integrity</span></b></p> 
  <p><span>It is important to minimize data corruption and inconsistency for medical
records, because they directly impact critical medical judgment and decisions.</span></p> 
  <p><b><span><span>3.<span> </span></span></span></b><b><span>Speed/Performance</span></b></p> 
  <p><span>Doctors work in a fast-paced environment and are not known for being
patient. WRS was looking for a database with high performance, and was aiming to
deliver the speed of an on-premise system with the SaaS model.</span></p> 
  <p><b><span><span>4.<span> </span></span></span></b><b><span>Low Cost and Scalability</span></b></p> 
  <p><span>WRS serves customers ranging from small practices to large enterprises. Therefore,
WRS needed a database solution that was affordable to the smallest healthcare
provider, while being able to scale to meet the demands of the largest
providers who have hundreds of facilities. <span> </span></span></p> 
  <p><b>The MySQL Solution</b></p> 
  <p><span>WRS evaluated
both MySQL and PostgreSQL for its EMR and Practice Management System, and
decided to use MySQL for the following reasons:</span></p> 
  <p><b><span><span>1.<span> </span></span></span></b><b><span>Ubiquity</span></b></p> 
  <p><span>MySQL is the world’s most popular open-source database with millions of
installations. It is widely used and is a proven technology.</span></p> 
  <p><b><span><span>2.<span> </span></span></span></b><b><span>Better Support</span></b></p> 
  <p><span>In addition to the community users who actively share knowledge and best
practices, it was also important for WRS to know that there is an enterprise
behind the product that they can turn to for help if needed. MySQL was created
by MySQL AB, and subsequently was developed and improved by Sun Microsystems
and now Oracle through acquisitions.It provides WRS with Scalability.</span></p> 
  <p><b><span><span>3.<span> </span></span></span></b><b><span>Open Source / Open Standard</span></b></p> 
  <p><span>MySQL is the “M” in the open-source LAMP (Linux, Apache, MySQL and PHP/Python/Perl)
stack. By leveraging and integrating the existing open-source technology, WRS
was able to develop products and features more quickly, and with better
interoperability.</span></p> 
  <p><span>WRS uses
MySQL replication to achieve scalability, deploying the master-slave topology.
“With MySQL, we can scale as we need. I can install it on many machines and
handle any required volume,” said Brad Hall, Systems Administrator at WRS. “This
gives us far more flexibility with hardware.” Three primary slaves all have to
handle the volume of over 6,000 queries per second throughout the day, and WRS
uses partitioning to increase speed.</span></p> 
  <p><span>With MySQL,
WRS was able to develop a modular EMR and Practice Management solution to support
thousands of medical practices, with the following features: electronic medical
and health records; billing; scheduling; electronic prescriptions; online
patient registration; practice website; messaging; order tracking;
transcription; document management; and disease management. “We required an
open source solution that was well maintained, stable, and actively growing. In
addition, we required a solution that offered access to enterprise support when
needed. MySQL was the right choice for us,” said Hall. “The performance,
scalability, and reliability delivered by MySQL with InnoDB has been excellent.”<a name="_GoBack"></a> </span></p> 
  <p><span>Learn more
about Waiting Room Solutions: </span><a href="http://www.waitingroomsolutions.com/"><span>http://www.waitingroomsolutions.com/</span></a><span></span></p> 
  <p><span>Read more
MySQL customer stories: </span><a href="http://www.mysql.com/customers/"><span>http://www.mysql.com/customers/</span></a><span> </span></p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33174&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33174&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 21:28:34 +0000</pubDate>
    <dc:creator>Oracle MySQL Group</dc:creator>
    <category>Community</category>
    <category>case</category>
    <category>mysql;</category>
    <category>room</category>
    <category>solutions</category>
    <category>study;</category>
    <category>waiting</category>
  </item>

  <item>
    <title>WordPress on S3: how it works</title>
    <guid isPermaLink="false">http://www.oblaksoft.com/?p=2533</guid>
    <link>http://www.oblaksoft.com/wordpress-on-s3-how-it-works/</link>
    <description>OblakSoft is pleased to showcase how simple it is to run LAMP applications on the cloud storage.  OblakSoft configured the WordPress web publishing platform to run on Amazon S3 storage and made the recipe available for anyone to replicate.  A ready-to-run WordPress site (configured as Yapixx) – is available for public use for FREE.  Yapixx is WordPress configured as a picture sharing website that runs on top of Amazon S3 (Yapixx stands for Yet Another Picture Sharing Site).

 
                                                                                                                                                                                       
Yapixx consists of the following software components:

         WordPress configured as a picture sharing site
         Yapixx theme based on zBench with modifications to look better for picture sharing
         wp2cloud plugin that stores pictures and other media in Amazon S3 via ClouSE
         LAMP software stack (Linux, Apache, MySQL, PHP)
         ClouSE &amp;#8211; the Cloud Storage Engine for MySQL

The Yapixx architecture looks like the following:
 

The WordPress platform provides the web user interface.  WordPress stores the web site content in a MySQL database.  MySQL uses ClouSE to store data in Amazon S3.  The end users use a web browser to interact with WordPress; web pages come from WordPress.  All the pictures (and other media) in the pages are served by Amazon S3, where they are stored as weblobs by WP2Cloud WordPress plugin.
WordPress is a mature and versatile platform that powers millions of websites with diverse purposes from blogging to social networking.  There are thousands of plugins and themes written for WordPress that can transform the website into pretty much anything.  And now with ClouSE WordPress can run on Amazon S3.
ClouSE is the key component of Yapixx application.  ClouSE is the Cloud Storage Engine for MySQL that can utilize cloud storage such as Amazon S3 to store user data.  Applications powered by ClouSE enjoy all the benefits of cloud storage – scaling cost with usage, high storage availability and reliability, quick and easy disaster recovery, etc.  And weblobs that store pictures for Yapixx can be served directly from cloud storage relying on its enormous power to make serving the content highly scalable.
ClouSE is the first and only relational database technology that overcomes cloud storage adoption barriers that prevents other databases from using cloud storage.  With ClouSE, cloud storage can be just plugged into a database server seamlessly and securely.
 

ClouSE and Amazon S3 provide seamless and secure data protection, scalability and availability for websites, static or dynamic.  A website on cloud storage has the following characteristics:

         Storage cost scales with usage, no upfront reservation is needed
         Storage consumption scales up and down with the amount of data stored
         Storage is extremely reliable and durable by Amazon S3 design
         Data is compressed, which significantly reduces storage size and cost
         Data is encrypted, which provides data confidentiality
         Pictures are served by Amazon S3 directly, which makes the website highly scalable
         No database backup and recovery is needed, which makes the website highly available

ClouSE brings the power of Amazon S3 to websites, providing an easy and inexpensive built-in solution for scenarios that previously required expensive infrastructure and operation.  Overprovisioning primary storage, implementing onsite + offsite backup and replication are not needed any more.  There is no need to implement and routinely test disaster recovery procedures.  No need to buy more expensive software editions.  The end-to-end data continuity is in the box: no extra tools, processes or equipment is required.  That’s the true realization of the cloud promise – commoditization and democratization of solutions that previously could only be afforded by large IT organizations with sizeable budgets.
The most amazing thing about Yapixx is that WordPress platform was not initially designed to store its data in cloud storage.  Yet, now it runs on Amazon S3 without any changes to the WordPress core engine!  We like to say that Yapixx was assembled and configured for the cloud, rather than designed and implemented for the cloud.
Launch your own WordPress site to the cloud today!  It’s easy and FREE, no writing code is required.  Start at http://www.oblaksoft.com/downloads.
We’d love to know what you think of Yapixx.  Are you considering to move your website to the cloud storage?
See also:
WordPress on S3: run a beautiful website on Amazon cloud storage.
WordPress on S3: the beauty of simplicity (blog).</description>
    <content:encoded><![CDATA[<p>OblakSoft is pleased to showcase how simple it is to run LAMP applications on the cloud storage.  OblakSoft configured the WordPress web publishing platform to run on Amazon S3 storage and made the recipe available for anyone to replicate.  A ready-to-run WordPress site (configured as <a href="https://www.oblaksoft.com/documentation/yapixx">Yapixx</a>) – is available for public use for FREE.  Yapixx is <a href="http://wordpress.org/">WordPress</a> configured as a picture sharing website that runs on top of <a href="http://aws.amazon.com/s3/">Amazon S3</a> (Yapixx stands for <strong>Y</strong>et <strong>A</strong>nother <strong>Pic</strong>ture <strong>S</strong>haring <strong>S</strong>ite).</p>
<p><span></span></p>
<p> <a href="http://www.oblaksoft.com/wp-content/uploads/2012/05/yapixx-logo.png"><img class="aligncenter  wp-image-2541" title="wordpres-on-s3-yapixx-logo" src="http://www.oblaksoft.com/wp-content/uploads/2012/05/yapixx-logo.png" alt="" width="298" height="149" /></a></p>
<p>                                                                                                                                                                                       </p>
<p>Yapixx consists of the following software components:</p>
<ul>
<li>         <a href="http://wordpress.org/">WordPress</a> configured as a picture sharing site</li>
<li>         Yapixx theme based on <a href="http://wordpress.org/extend/themes/zbench">zBench</a> with modifications to look better for picture sharing</li>
<li>         <a href="https://www.oblaksoft.com/documentation/yapixx">wp2cloud</a> plugin that stores pictures and other media in Amazon S3 via ClouSE</li>
<li>         LAMP software stack (Linux, <a href="http://httpd.apache.org/">Apache</a>, <a href="http://www.mysql.com/">MySQL</a>, <a href="http://www.php.net/">PHP</a>)</li>
<li>         <a href="https://www.oblaksoft.com/documentation">ClouSE</a> &#8211; the Cloud Storage Engine for MySQL</li>
</ul>
<p>The Yapixx architecture looks like the following:<br />
 <a href="http://www.oblaksoft.com/wp-content/uploads/2012/05/yapixx-architecture.png"><img class="aligncenter size-full wp-image-2543" title="wordpress-on-s3-yapixx-architecture" src="http://www.oblaksoft.com/wp-content/uploads/2012/05/yapixx-architecture.png" alt="" width="542" height="338" /></a></p>
<div></div>
<p>The WordPress platform provides the web user interface.  WordPress stores the web site content in a MySQL database.  MySQL uses ClouSE to store data in Amazon S3.  The end users use a web browser to interact with WordPress; web pages come from WordPress.  All the pictures (and other media) in the pages are served by Amazon S3, where they are stored as <a href="https://www.oblaksoft.com/documentation/faq/#_weblob">weblobs</a> by WP2Cloud WordPress plugin.</p>
<p>WordPress is a mature and versatile platform that powers millions of websites with diverse purposes from blogging to social networking.  There are thousands of plugins and themes written for WordPress that can transform the website into pretty much anything.  And now with ClouSE WordPress can run on Amazon S3.</p>
<p>ClouSE is the key component of Yapixx application.  ClouSE is the Cloud Storage Engine for <a href="http://www.mysql.com/">MySQL</a> that can utilize cloud storage such as <a href="http://aws.amazon.com/s3/">Amazon S3</a> to store user data.  Applications powered by ClouSE enjoy all the benefits of cloud storage – scaling cost with usage, high storage availability and reliability, quick and easy disaster recovery, etc.  And weblobs that store pictures for Yapixx can be served directly from cloud storage relying on its enormous power to make serving the content highly scalable.</p>
<p>ClouSE is the first and only relational database technology that overcomes cloud storage adoption barriers that prevents other databases from using cloud storage.  With ClouSE, cloud storage can be just plugged into a database server seamlessly and securely.</p>
<p> <a href="http://www.oblaksoft.com/wp-content/uploads/2011/12/ClouSE_Logo11.png"><img class="aligncenter size-full wp-image-2251" title="ClouSE_Logo" src="http://www.oblaksoft.com/wp-content/uploads/2011/12/ClouSE_Logo11.png" alt="" width="376" height="149" /></a></p>
<div></div>
<p>ClouSE and Amazon S3 provide seamless and secure data protection, scalability and availability for websites, static or dynamic.  A website on cloud storage has the following characteristics:</p>
<ul>
<li>         Storage cost scales with usage, no upfront reservation is needed</li>
<li>         Storage consumption scales up and down with the amount of data stored</li>
<li>         Storage is extremely reliable and durable by Amazon S3 design</li>
<li>         Data is compressed, which significantly reduces storage size and cost</li>
<li>         Data is encrypted, which provides data confidentiality</li>
<li>         Pictures are served by Amazon S3 directly, which makes the website highly scalable</li>
<li>         No database backup and recovery is needed, which makes the website highly available</li>
</ul>
<p>ClouSE brings the power of Amazon S3 to websites, providing an easy and inexpensive built-in solution for scenarios that previously required expensive infrastructure and operation.  Overprovisioning primary storage, implementing onsite + offsite backup and replication are not needed any more.  There is no need to implement and routinely test disaster recovery procedures.  No need to buy more expensive software editions.  The end-to-end data continuity is in the box: no extra tools, processes or equipment is required.  That’s the true realization of the cloud promise – commoditization and democratization of solutions that previously could only be afforded by large IT organizations with sizeable budgets.</p>
<p>The most amazing thing about Yapixx is that WordPress platform was <em>not</em> initially designed to store its data in cloud storage.  Yet, now it runs on Amazon S3 without any changes to the WordPress core engine!  We like to say that Yapixx was <em>assembled</em> and <em>configured</em> for the cloud, rather than designed and implemented for the cloud.</p>
<p>Launch your own WordPress site to the cloud today!  It’s easy and FREE, no writing code is required.  Start at <a href="http://www.oblaksoft.com/downloads">http://www.oblaksoft.com/downloads</a>.</p>
<p>We’d love to know what you think of Yapixx.  Are you considering to move your website to the cloud storage?</p>
<p><em><strong>See also:</strong></em></p>
<p>WordPress on S3: <a href="http://www.oblaksoft.com/wordpress-on-s3-newsletter-may-2012">run a beautiful website on Amazon cloud storage</a>.</p>
<p>WordPress on S3: <a href="http://www.oblaksoft.com/wordpress-on-s3-the-beauty-of-simplicity/" />the beauty of simplicity (blog)<a>.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33175&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33175&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 21:00:50 +0000</pubDate>
    <dc:creator>Artem Livshits</dc:creator>
    <category>Founders BLOG</category>
    <category>cloud</category>
    <category>LAMPS3</category>
    <category>MySQL</category>
    <category>S3</category>
    <category>website</category>
    <category>Wordpress</category>
  </item>

  <item>
    <title>Webinar 5/17: MySQL High Availability Realized</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-5088740386330348582.post-876909813739370225</guid>
    <link>http://continuent-tungsten.blogspot.com/2012/05/webinar-517-mysql-high-availability.html</link>
    <description>High availability is about more than just making sure that applications can get to your data, even if there is a failure:

How about when you are upgrading your database schema 
What if you need to add memory to a database server or reconfigure/restart MySQL
If your apps want to read data from a MySQL slave, how can you be sure they are not reading stale data without re-coding your apps
What</description>
    <content:encoded><![CDATA[High availability is about more than just making sure that applications can get to your data, even if there is a failure:

How about when you are upgrading your database schema 
What if you need to add memory to a database server or reconfigure/restart MySQL
If your apps want to read data from a MySQL slave, how can you be sure they are not reading stale data without re-coding your apps
What<br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33173&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33173&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 20:56:00 +0000</pubDate>
    <dc:creator>Petri Virsunen</dc:creator>
    <category>MySQL</category>
    <category>high availability</category>
    <category>multi-master</category>
    <category>replication</category>
    <category>multi-site</category>
    <category>Continuent Tungsten</category>
  </item>

  <item>
    <title>MySQL Utilities Frequently Asked Questions</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-2959317805805542041.post-8307641094060823604</guid>
    <link>http://drcharlesbell.blogspot.com/2012/05/mysql-utilities-frequently-asked.html</link>
    <description>Momentum for MySQL Utilities continues to build.  I hosted a webinar recently about MySQL Utilities (available on-demand from the link below), which generated a lot of interest and some good questions. http://event.on24.com/eventRegistration/EventLobbyServlet?target=lobby.jsp&amp;eventid=448952&amp;sessionid=1&amp;key=7E741ED049DFBF49D10C90A2B62E410F&amp;eventuserid=63530507With so many questions and ideas coming in I decided to create a blog of FAQs. I plan to add these to the MySQL documentation as well.  Keep your ideas and questions coming!I hope you find these questions enlightening. I have grouped them for easier reading. You can find the MySQL Utilities documentation using the link below. http://dev.mysql.com/doc/workbench/en/mysql-utilities.htmlGeneralAre these utilities present in the community version of MySQL?They are included in the community edition of the MySQL Workbench product, which can be downloaded from the following link. http://www.mysql.com/downloads/workbench/Should/can we run this on live data?Yes. Naturally, you would want to test some operations before jumping directly into a production environment. For example, you may want to test any database migration, transformation, or similar massive change in a test environment. Can we use the utilities in a production environment under the GPL license?Yes. MySQL Utilities is part of MySQL Workbench so all such licenses apply accordingly.Storage EnginesCan the utilities be used with MyISAM or CSV?Yes. There are no storage engine specific limitations in using the utilities. There are some features written specifically for InnoDB so those may not apply but in general no utility is storage engine specific. For example, the mysqldiskusage utility shows exact sizes for MyISAM and InnoDB files but uses estimated sizes for any other storage engine based on number of rows and row size.PlatformsCan I use MySQL Utilities on Linux?Yes. MySQL Utilities runs on all platforms supported by MySQL Workbench.Can the utilities be used on Windows?Yes!Do the utilities work both for window-based and linux-based servers?Yes! They work for any server hosting MySQL.InstallationDo we have to install the utilities with rpm or can we use the tar ball extract and run from there?MySQL Utilities is installed as part of MySQL Workbench. You can download and install Workbench using several platform-specific installers. You can also branch and download MySQL Utilities from Launchpad. You can also build and install it from the source code you’ve downloaded using typical Python install steps (python ./setup.py install). https://launchpad.net/mysql-utilitiesWhat's the link to download these utilities?MySQL Utilities is part of MySQL Workbench. You can download MySQL Workbench from the following link.http://www.mysql.com/downloads/workbench/LockingDo the utilities lock tables while running?Yes, but only for situations that require locks. The mysqldbexport utility also allows you to specify what type of lock to use: no-locks = do not use any table lockslock-all = use table locks but no transaction and no consistent readsnaphot (default) = consistent read using a single transaction.Are there any utilities that can show DB locks (like which query is blocking which one)?No, not currently but that is an excellent suggestion!mysqldbcompareHow fast is mysqldbcompare? Say a table with 10 million rows?It is difficult to predict a precise estimate of run time based on number of rows. However, it is generally such that the more rows there are the longer the utility will run. The mysqldbcompare utility is used to produce a difference of two databases. It creates a difference between objects of the same name for either object definitions, data, or both. When comparing object definitions, the performance is very fast because there isn’t a lot of processing involved. When comparing data, the utility uses an algorithm to create checksums for each row in the table. During this phase, the tables are locked. Once that stage is done, the tables are unlocked and the algorithm begins to compact the checksums into chunks, which are later compared between the servers. If the checksums differ, the chunks are expanded and the differences calculated. Thus, for tables containing millions of rows the utility will take some time to complete. The best time to run this utility is during low usage periods such as times reserved for upgrades, backups, and similar operations.How will running mysqldbcompare effect a production database?If generating a difference for data, the utility will lock the tables long enough to calculate a checksum for each row. Depending on the number of rows this could be for a long time and in those cases you should run mysqldbcompare during low usage periods. The utility will use a consistent read to lock InnoDB tables but will issue table locks for non-InnoDB tables.Will mysqldbcompare cause table locking on MyISAM table?Yes. A table lock is issued during checksum creation.What is the load going to be on the servers when mysqldbcompare runs?The load on the server itself is minimal. There is moderate CPU usage during checksum creation but nothing that should cause a problem. The longest period of activity is when the table scans are executed for creating a checksum for each row.mysqldbexportIs mysqldbexport similar to mysqldump?Yes, the mysqldbexport is designed to export data in a row-by-row or logical fashion. However, you can export data in CSV, TAB, Vertical formats as well as SQL statements using CREATE TABLE, INSERT, etc. making mysqldbexport more versatile than mysqldump. You would use mysqldbexport in situations where you need special machine or human readable output for operations like transforming the data or examining the structures in more detail – especially if you need a format other than SQL statements.Replication UtilitiesAre the high availability features available for version 5.5 or 5.6?The general replication utilities such as mysqlrplcheck and mysqlreplicate will work with servers version 5.0 and later. The newest high availability feature, failover, in mysqlrpladmin and mysqlfailover work only for servers that support global transaction identifiers (GTIDs) which were added in version 5.6.5. You can discover more about GTIDs from the following blog by Luis Soares.http://d2-systems.blogspot.co.uk/2012/04/global-transaction-identifiers-are-in.htmlWhere do I get more info about mysqlrpladmin?The online MySQL Workbench Manual has information about each utility. You can also use the --help option to show all options and their descriptions.http://dev.mysql.com/doc/workbench/en/mysql-utilities.htmlHow can I use the utilities to test replication on a single host?You can use mysqlserverclone to clone an existing, running instance of MySQL or clone from an installation (basedir), then mysqlreplicate to create the replication topology. Is the replication failover feature only for version 5.6? Yes. It requires support for global transaction identifiers, which were added in version 5.6.5. A developer milestone release of 5.6 is available for download.http://dev.mysql.com/downloads/mysql/#downloads(Select the Development Releases tab)What features of mysqlrpladmin will work on version 5.5?All of the features except slave election and failover.Do you need to create a replication user on the slave site other than the master?The mysqlreplicate utility provides an option to use a specific user on the master for replication or it will create a user by default. You can also request that a new user be created during the operation.</description>
    <content:encoded><![CDATA[<p>Momentum for MySQL Utilities continues to build.  I hosted a webinar recently about MySQL Utilities (available on-demand from the link below), which generated a lot of interest and some good questions. </p><p><a href="http://event.on24.com/eventRegistration/EventLobbyServlet?target=lobby.jsp&amp;eventid=448952&amp;sessionid=1&amp;key=7E741ED049DFBF49D10C90A2B62E410F&amp;eventuserid=63530507">http://event.on24.com/eventRegistration/EventLobbyServlet?target=lobby.jsp&eventid=448952&sessionid=1&key=7E741ED049DFBF49D10C90A2B62E410F&eventuserid=63530507</a></p><p>With so many questions and ideas coming in I decided to create a blog of FAQs. I plan to add these to the MySQL documentation as well.  Keep your ideas and questions coming!</p><p>I hope you find these questions enlightening. I have grouped them for easier reading. You can find the MySQL Utilities documentation using the link below. </p><p><a href="http://dev.mysql.com/doc/workbench/en/mysql-utilities.html">http://dev.mysql.com/doc/workbench/en/mysql-utilities.html</a></p><p><strong>General</strong></p><p><em>Are these utilities present in the community version of MySQL?</em></p><p>They are included in the community edition of the MySQL Workbench product, which can be downloaded from the following link. </p><p><a href="http://www.mysql.com/downloads/workbench/">http://www.mysql.com/downloads/workbench/</a></p><p><em>Should/can we run this on live data?</em></p><p>Yes. Naturally, you would want to test some operations before jumping directly into a production environment. For example, you may want to test any database migration, transformation, or similar massive change in a test environment. </p><p><em>Can we use the utilities in a production environment under the GPL license?</em></p><p>Yes. MySQL Utilities is part of MySQL Workbench so all such licenses apply accordingly.</p><p><strong>Storage Engines</strong></p><p><em>Can the utilities be used with MyISAM or CSV?</em></p><p>Yes. There are no storage engine specific limitations in using the utilities. There are some features written specifically for InnoDB so those may not apply but in general no utility is storage engine specific. For example, the mysqldiskusage utility shows exact sizes for MyISAM and InnoDB files but uses estimated sizes for any other storage engine based on number of rows and row size.</p><p><strong>Platforms</strong></p><p><em>Can I use MySQL Utilities on Linux?</em></p><p>Yes. MySQL Utilities runs on all platforms supported by MySQL Workbench.</p><p><em>Can the utilities be used on Windows?</em></p><p>Yes!</p><p><em>Do the utilities work both for window-based and linux-based servers?</em></p><p>Yes! They work for any server hosting MySQL.</p><p><strong>Installation</strong></p><p><em>Do we have to install the utilities with rpm or can we use the tar ball extract and run from there?</em></p><p>MySQL Utilities is installed as part of MySQL Workbench. You can download and install Workbench using several platform-specific installers. </p><p>You can also branch and download MySQL Utilities from Launchpad. You can also build and install it from the source code you’ve downloaded using typical Python install steps (python ./setup.py install). </p><p><a href="https://launchpad.net/mysql-utilities">https://launchpad.net/mysql-utilities</a></p><p><em>What's the link to download these utilities?</em></p><p>MySQL Utilities is part of MySQL Workbench. You can download MySQL Workbench from the following link.</p><p><a href="http://www.mysql.com/downloads/workbench/">http://www.mysql.com/downloads/workbench/</a></p><p><strong>Locking</strong></p><p><em>Do the utilities lock tables while running?</em></p><p>Yes, but only for situations that require locks. The mysqldbexport utility also allows you to specify what type of lock to use: </p><p>no-locks = do not use any table locks</p><p>lock-all = use table locks but no transaction and no consistent read</p><p>snaphot (default) = consistent read using a single transaction.</p><p><em>Are there any utilities that can show DB locks (like which query is blocking which one)?</em></p><p>No, not currently but that is an excellent suggestion!</p><p><strong>mysqldbcompare</strong></p><p><em>How fast is mysqldbcompare? Say a table with 10 million rows?</em></p><p>It is difficult to predict a precise estimate of run time based on number of rows. However, it is generally such that the more rows there are the longer the utility will run. The mysqldbcompare utility is used to produce a difference of two databases. It creates a difference between objects of the same name for either object definitions, data, or both. When comparing object definitions, the performance is very fast because there isn’t a lot of processing involved. When comparing data, the utility uses an algorithm to create checksums for each row in the table. During this phase, the tables are locked. Once that stage is done, the tables are unlocked and the algorithm begins to compact the checksums into chunks, which are later compared between the servers. If the checksums differ, the chunks are expanded and the differences calculated. Thus, for tables containing millions of rows the utility will take some time to complete. The best time to run this utility is during low usage periods such as times reserved for upgrades, backups, and similar operations.</p><p><em>How will running mysqldbcompare effect a production database?</em></p><p>If generating a difference for data, the utility will lock the tables long enough to calculate a checksum for each row. Depending on the number of rows this could be for a long time and in those cases you should run mysqldbcompare during low usage periods. The utility will use a consistent read to lock InnoDB tables but will issue table locks for non-InnoDB tables.</p><p><em>Will mysqldbcompare cause table locking on MyISAM table?</em></p><p>Yes. A table lock is issued during checksum creation.</p><p><em>What is the load going to be on the servers when mysqldbcompare runs?</em></p><p>The load on the server itself is minimal. There is moderate CPU usage during checksum creation but nothing that should cause a problem. The longest period of activity is when the table scans are executed for creating a checksum for each row.</p><p><strong>mysqldbexport</strong></p><p><em>Is mysqldbexport similar to mysqldump?</em></p><p>Yes, the mysqldbexport is designed to export data in a row-by-row or logical fashion. However, you can export data in CSV, TAB, Vertical formats as well as SQL statements using CREATE TABLE, INSERT, etc. making mysqldbexport more versatile than mysqldump. You would use mysqldbexport in situations where you need special machine or human readable output for operations like transforming the data or examining the structures in more detail – especially if you need a format other than SQL statements.</p><p><strong>Replication Utilities</strong></p><p><em>Are the high availability features available for version 5.5 or 5.6?</em></p><p>The general replication utilities such as mysqlrplcheck and mysqlreplicate will work with servers version 5.0 and later. The newest high availability feature, failover, in mysqlrpladmin and mysqlfailover work only for servers that support global transaction identifiers (GTIDs) which were added in version 5.6.5. </p><p>You can discover more about GTIDs from the following blog by Luis Soares.</p><p><a href="http://d2-systems.blogspot.co.uk/2012/04/global-transaction-identifiers-are-in.html">http://d2-systems.blogspot.co.uk/2012/04/global-transaction-identifiers-are-in.html</a></p><p><em>Where do I get more info about mysqlrpladmin?</em></p><p>The online MySQL Workbench Manual has information about each utility. You can also use the --help option to show all options and their descriptions.</p><p><a href="http://dev.mysql.com/doc/workbench/en/mysql-utilities.html">http://dev.mysql.com/doc/workbench/en/mysql-utilities.html</a></p><p><em>How can I use the utilities to test replication on a single host?</em></p><p>You can use mysqlserverclone to clone an existing, running instance of MySQL or clone from an installation (basedir), then mysqlreplicate to create the replication topology. </p><p><em>Is the replication failover feature only for version 5.6? </em></p><p>Yes. It requires support for global transaction identifiers, which were added in version 5.6.5. A developer milestone release of 5.6 is available for download.</p><p><a href="http://dev.mysql.com/downloads/mysql/#downloads">http://dev.mysql.com/downloads/mysql/#downloads</a></p><p>(Select the Development Releases tab)</p><p><em>What features of mysqlrpladmin will work on version 5.5?</em></p><p>All of the features except slave election and failover.</p><p><em>Do you need to create a replication user on the slave site other than the master?</em></p><p>The mysqlreplicate utility provides an option to use a specific user on the master for replication or it will create a user by default. You can also request that a new user be created during the operation.</p><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/2959317805805542041-8307641094060823604?l=drcharlesbell.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33171&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33171&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 20:01:00 +0000</pubDate>
    <dc:creator>Chuck Bell</dc:creator>
    <category>mysql</category>
    <category>utilities</category>
    <category>administration</category>
    <category>workbench</category>
    <category>database</category>
  </item>

  <item>
    <title>Compare and Synchronize Databases with MySQL Utilities</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-2959317805805542041.post-3973032454519382820</guid>
    <link>http://drcharlesbell.blogspot.com/2012/05/compare-and-synchronize-databases-with.html</link>
    <description>The mysqldiff and mysqldbcompare utilities were designed to produce a difference report for objects and in the case of mysqldbcompare the data. Thus, you can compare two databases and produce a report of the differences in both object definitions and data rows.&amp;nbsp;While that may be very useful, would it not be much more useful to have the ability to produce SQL commands to transform databases?  Wait no longer! The latest release of MySQL Utilities has added the ability to generate SQL transformation statements by both the mysqldiff and mysqldbcompare utilities.&amp;nbsp;To generate SQL transformations in either utility, simply use the --sql option to tell the utility to produce the statements.Object Transformations with mysqldiffIf you would like to compare the schema of two databases (the objects and their definitions), mysqldiff can do that for you and produce a difference report in a number of formats including CSV, TAB, GRID, and Vertical (like the mysql client’s \G option). However, its greatest feature is the ability to generate transformation statements to alter the objects so that they conform. Best of all, mysqldiff works on all object types including the ability to recognize renames so you can get a true transformation path for all objects. For even greater flexibility, you can generate the difference in both directions. This means you can generate transformations for db1-to-db2 as well as db2-to-db1 in the same pass. Cool.The following shows an example of running mysqldiff on two servers where some of the objects have diverged. It also shows how you can generate the reverse transformation statements.$ mysqldiff --server1=root@localhost --server2=root@otherhost \--changes-for=server1 --show-reverse util_test:util_test \--force --difftype=SQL# server1 on localhost: ... connected.# server2 on localhost: ... connected.# WARNING: Objects in server1.util_test but not in server2.util_test:# EVENT: e1# Comparing util_test to util_test [PASS]# Comparing util_test.f1 to util_test.f1 [PASS]# Comparing util_test.p1 to util_test.p1 [PASS]# Comparing util_test.t1 to util_test.t1 [PASS]# Comparing util_test.t2 to util_test.t2 [PASS]# Comparing util_test.t3 to util_test.t3 [FAIL]# Transformation for --changes-for=server1:#ALTER TABLE util_test.t3 DROP COLUMN b, ADD COLUMN d char(30) NULL AFTER a ENGINE=MyISAM;## Transformation for reverse changes (--changes-for=server2):## ALTER TABLE util_test.t3 # DROP COLUMN d, # ADD COLUMN b char(30) NULL AFTER a, # ENGINE=InnoDB;## Comparing util_test.trg to util_test.trg [FAIL]# Transformation for --changes-for=server1:#DROP TRIGGER IF EXISTS `util_test`.`trg`;CREATE DEFINER=root@localhost TRIGGER util_test.trg BEFORE UPDATE ON util_test.t1 FOR EACH ROW INSERT INTO util_test.t1 VALUES('Wax on, wax off');## Transformation for reverse changes (--changes-for=server2):## DROP TRIGGER IF EXISTS `util_test`.`trg`;# CREATE DEFINER=root@localhost TRIGGER util_test.trg AFTER INSERT ON util_test.t1 # FOR EACH ROW INSERT INTO util_test.t2 VALUES('Test objects count');## Comparing util_test.v1 to util_test.v1 [FAIL]# Transformation for --changes-for=server1:#ALTER VIEW util_test.v1 AS select `util_test`.`t2`.`a` AS `a` from `util_test`.`t2`;## Transformation for reverse changes (--changes-for=server2):## ALTER VIEW util_test.v1 AS # select `util_test`.`t1`.`a` AS `a` from `util_test`.`t1`;#Compare failed. One or more differences found.Generating Data Transformation with mysqldbcompareThe mysqldbcompare utility provides all of the object difference functionality included in mysqldiff along with the ability to generate transformation SQL statements for data. This means you can make sure your test or development databases are similar to your production databases or perhaps even your offline, read only databases match your online databases. Like mysqldiff, you can also get the reverse transformations at the same time. Very cool, eh?The following shows an example of running mysqldbcompare to generate differences in data.$ mysqldbcompare --server1=root@localhost --server2=root@otherhost \inventory:inventory -a --difftype=sql --changes-for=server1 \--show-reverse# server1 on localhost: ... connected.# server2 on localhost: ... connected.# Checking databases inventory on server1 and inventory on server2## WARNING: Objects in server1.inventory but not in server2.inventory:#         VIEW: finishing_up#         VIEW: cleaning#[...] # TABLE     supplier                                pass    FAIL    FAIL    ## Row counts are not the same among inventory.supplier and inventory.supplier.## Transformation for --changes-for=server1:## Data differences found among rows:UPDATE inventory.supplier SET name = 'Wesayso Corporation' WHERE code = '2';INSERT INTO inventory.supplier (code, name) VALUES('3', 'Never Enough Inc.');## Transformation for reverse changes (--changes-for=server2):## # Data differences found among rows:# UPDATE inventory.supplier SET name = 'Never Enough Inc.' WHERE code = '2';# DELETE FROM inventory.supplier WHERE code = '3';## Database consistency check failed.## ...done</description>
    <content:encoded><![CDATA[<span>The mysqldiff and mysqldbcompare utilities were designed to produce a difference report for objects and in the case of mysqldbcompare the data. Thus, you can compare two databases and produce a report of the differences in both object definitions and data rows.&nbsp;</span><br /><br /><span>While that may be very useful, would it not be much more useful to have the ability to produce SQL commands to transform databases?  Wait no longer! The latest release of MySQL Utilities has added the ability to generate SQL transformation statements by both the mysqldiff and mysqldbcompare utilities.&nbsp;</span><br /><br /><span>To generate SQL transformations in either utility, simply use the --sql option to tell the utility to produce the statements.</span><br /><br /><span><b>Object Transformations with mysqldiff</b></span><br /><br /><span>If you would like to compare the schema of two databases (the objects and their definitions), mysqldiff can do that for you and produce a difference report in a number of formats including CSV, TAB, GRID, and Vertical (like the mysql client’s \G option). </span><br /><br /><span>However, its greatest feature is the ability to generate transformation statements to alter the objects so that they conform. Best of all, mysqldiff works on all object types including the ability to recognize renames so you can get a true transformation path for all objects. For even greater flexibility, you can generate the difference in both directions. This means you can generate transformations for db1-to-db2 as well as db2-to-db1 in the same pass. Cool.</span><br /><br /><span>The following shows an example of running mysqldiff on two servers where some of the objects have diverged. It also shows how you can generate the reverse transformation statements.</span><br /><br /><span><br style="font-family: &quot;Courier New&quot;,Courier,monospace;" /></span><span><span>$ mysqldiff --server1=root@localhost --server2=root@otherhost \</span></span><br /><span><span>--changes-for=server1 --show-reverse util_test:util_test \</span></span><br /><span><span>--force --difftype=SQL</span></span><br /><span><span># server1 on localhost: ... connected.</span></span><br /><span><span># server2 on localhost: ... connected.</span></span><br /><span><span># WARNING: Objects in server1.util_test but not in server2.util_test:</span></span><br /><span><span># EVENT: e1</span></span><br /><span><span># Comparing util_test to util_test [PASS]</span></span><br /><span><span># Comparing util_test.f1 to util_test.f1 [PASS]</span></span><br /><span><span># Comparing util_test.p1 to util_test.p1 [PASS]</span></span><br /><span><span># Comparing util_test.t1 to util_test.t1 [PASS]</span></span><br /><span><span># Comparing util_test.t2 to util_test.t2 [PASS]</span></span><br /><span><span># Comparing util_test.t3 to util_test.t3 [FAIL]</span></span><br /><span><span># Transformation for --changes-for=server1:</span></span><br /><span><span>#</span></span><br /><span><span>ALTER TABLE util_test.t3 </span></span><br /><span><span>DROP COLUMN b, </span></span><br /><span><span>ADD COLUMN d char(30) NULL AFTER a </span></span><br /><span><span>ENGINE=MyISAM;</span></span><br /><span><span>#</span></span><br /><span><span># Transformation for reverse changes (--changes-for=server2):</span></span><br /><span><span>#</span></span><br /><span><span># ALTER TABLE util_test.t3 </span></span><br /><span><span># DROP COLUMN d, </span></span><br /><span><span># ADD COLUMN b char(30) NULL AFTER a, </span></span><br /><span><span># ENGINE=InnoDB;</span></span><br /><span><span>#</span></span><br /><span><span># Comparing util_test.trg to util_test.trg [FAIL]</span></span><br /><span><span># Transformation for --changes-for=server1:</span></span><br /><span><span>#</span></span><br /><span><span>DROP TRIGGER IF EXISTS `util_test`.`trg`;</span></span><br /><span><span>CREATE DEFINER=root@localhost TRIGGER util_test.trg BEFORE UPDATE ON util_test.t1 </span></span><br /><span><span>FOR EACH ROW INSERT INTO util_test.t1 VALUES('Wax on, wax off');</span></span><br /><span><span>#</span></span><br /><span><span># Transformation for reverse changes (--changes-for=server2):</span></span><br /><span><span>#</span></span><br /><span><span># DROP TRIGGER IF EXISTS `util_test`.`trg`;</span></span><br /><span><span># CREATE DEFINER=root@localhost TRIGGER util_test.trg AFTER INSERT ON util_test.t1 </span></span><br /><span><span># FOR EACH ROW INSERT INTO util_test.t2 VALUES('Test objects count');</span></span><br /><span><span>#</span></span><br /><span><span># Comparing util_test.v1 to util_test.v1 [FAIL]</span></span><br /><span><span># Transformation for --changes-for=server1:</span></span><br /><span><span>#</span></span><br /><span><span>ALTER VIEW util_test.v1 AS </span></span><br /><span><span>select `util_test`.`t2`.`a` AS `a` from `util_test`.`t2`;</span></span><br /><span><span>#</span></span><br /><span><span># Transformation for reverse changes (--changes-for=server2):</span></span><br /><span><span>#</span></span><br /><span><span># ALTER VIEW util_test.v1 AS </span></span><br /><span><span># select `util_test`.`t1`.`a` AS `a` from `util_test`.`t1`;</span></span><br /><span><span>#</span></span><br /><span><span>Compare failed. One or more differences found.</span></span><br /><br /><span><b>Generating Data Transformation with mysqldbcompare</b></span><br /><br /><span>The mysqldbcompare utility provides all of the object difference functionality included in mysqldiff along with the ability to generate transformation SQL statements for data. This means you can make sure your test or development databases are similar to your production databases or perhaps even your offline, read only databases match your online databases. Like mysqldiff, you can also get the reverse transformations at the same time. Very cool, eh?</span><br /><br /><span>The following shows an example of running mysqldbcompare to generate differences in data.</span><br /><br /><div><span>$ mysqldbcompare --server1=root@localhost --server2=root@otherhost \</span></div><div><span>inventory:inventory -a --difftype=sql --changes-for=server1 \</span></div><div><span>--show-reverse</span></div><div><span># server1 on localhost: ... connected.</span></div><div><span># server2 on localhost: ... connected.</span></div><div><span># Checking databases inventory on server1 and inventory on server2</span></div><div><span>#</span></div><div><span># WARNING: Objects in server1.inventory but not in server2.inventory:</span></div><div><span>#         VIEW: finishing_up</span></div><div><span>#         VIEW: cleaning</span></div><div><span>#</span></div><div><span><br /></span></div><div><span>[...] </span></div><div><span><br /></span></div><div></div><div><span></span><span># TABLE     supplier                                pass    FAIL    FAIL    </span></div><div><span>#</span></div><div><span># Row counts are not the same among inventory.supplier and inventory.supplier.</span></div><div><span>#</span></div><div><span># Transformation for --changes-for=server1:</span></div><div><span>#</span></div><div><span># Data differences found among rows:</span></div><div><span>UPDATE inventory.supplier SET name = 'Wesayso Corporation' WHERE code = '2';</span></div><div><span>INSERT INTO inventory.supplier (code, name) VALUES('3', 'Never Enough Inc.');</span></div><div><span>#</span></div><div><span># Transformation for reverse changes (--changes-for=server2):</span></div><div><span>#</span></div><div><span># # Data differences found among rows:</span></div><div><span># UPDATE inventory.supplier SET name = 'Never Enough Inc.' WHERE code = '2';</span></div><div><span># DELETE FROM inventory.supplier WHERE code = '3';</span></div><div><span>#</span></div><div><span># Database consistency check failed.</span></div><div><span>#</span></div><div><span># ...done</span></div><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/2959317805805542041-3973032454519382820?l=drcharlesbell.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33172&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33172&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 19:45:00 +0000</pubDate>
    <dc:creator>Chuck Bell</dc:creator>
    <category>synchronization</category>
    <category>mysql</category>
    <category>compare</category>
    <category>administration</category>
    <category>workbench</category>
    <category>database</category>
  </item>

  <item>
    <title>How To Back Up MySQL Databases With mylvmbackup On Debian Squeeze</title>
    <guid isPermaLink="false">http://www.howtoforge.com/how-to-back-up-mysql-databases-with-mylvmbackup-on-debian-squeeze</guid>
    <link>http://www.howtoforge.com/how-to-back-up-mysql-databases-with-mylvmbackup-on-debian-squeeze</link>
    <description>
How To Back Up MySQL Databases With mylvmbackup On Debian Squeeze

mylvmbackup
 is a Perl script for quickly creating MySQL backups. It uses LVM's 
snapshot feature to do so. To perform a backup, mylvmbackup obtains a 
read lock on all tables and flushes all server caches to disk, creates a
 snapshot of the volume containing the MySQL data directory, and unlocks
 the tables again. This article shows how to use it on a Debian Squeeze 
server.</description>
    <content:encoded><![CDATA[<table align="left" cellpadding="0" cellspacing="0" width="71" height="40"><tr><td><img class="teaser-image-even" src="http://static.howtoforge.com/images/teaser/mysql_neu.gif" width="68" height="40" alt="" /></td></tr></table>
<p><b>How To Back Up MySQL Databases With mylvmbackup On Debian Squeeze</b></p>

<p>mylvmbackup
 is a Perl script for quickly creating MySQL backups. It uses LVM's 
snapshot feature to do so. To perform a backup, mylvmbackup obtains a 
read lock on all tables and flushes all server caches to disk, creates a
 snapshot of the volume containing the MySQL data directory, and unlocks
 the tables again. This article shows how to use it on a Debian Squeeze 
server.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33170&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33170&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 15:49:37 +0000</pubDate>
    <category>Debian</category>
    <category>Backup</category>
    <category>MySQL</category>
  </item>

  <item>
    <title>MONyog MySQL Monitor 5.2 Has Been Released</title>
    <guid isPermaLink="false">http://www.webyog.com/blog/?p=3729</guid>
    <link>http://www.webyog.com/blog/2012/05/09/monyog-mysql-monitor-5-2-has-been-released/</link>
    <description>IMPORTANT note:
* This release requires a new registration code. Neither the 5.1x nor the pre-5.1x key will work with this. Registered customers will get the new code from our Customer Portal. Please have the new code available before installing. Until MONyog is registered with new keys, it will not be collecting data from your servers .
Features:
* Added filter for including or excluding specific hosts and(or) users in slow log analysis.
* Added and modified a few Monitors related to Replication, InnoDB and Security. Most of this utilizes metrics exposed by MySQL from version 5.5 .
* Added a preconfigured Custom SQL Object (CSO) for Percona Servers exposing the most written and most read tables.
* There is now session-wide persistence while sorting columns in Query Analyzer.
* Improved error messages in Query Analyzer and Wayback machine.
* Usability enhancements, GUI fixes and internal optimizations.
Bug fixes:
* MONyog was not working while behind Apache configured as a reverse proxy. This bug was introduced in MONyog 5.0.
Downloads: http://webyog.com/en/downloads.php
Purchase: http://webyog.com/en/buy.php


Tweet
</description>
    <content:encoded><![CDATA[<p><strong>IMPORTANT note:</strong><br />
* This release requires a new registration code. Neither the 5.1x nor the pre-5.1x key will work with this. Registered customers will get the new code from our Customer Portal. Please have the new code available before installing. Until MONyog is registered with new keys, it will not be collecting data from your servers .</p>
<p><strong>Features<strong>:</strong><br />
</strong>* Added filter for including or excluding specific hosts and(or) users in slow log analysis.<br />
* Added and modified a few Monitors related to Replication, InnoDB and Security. Most of this utilizes metrics exposed by MySQL from version 5.5 .<br />
* Added a preconfigured Custom SQL Object (CSO) for Percona Servers exposing the most written and most read tables.<br />
* There is now session-wide persistence while sorting columns in Query Analyzer.<br />
* Improved error messages in Query Analyzer and Wayback machine.<br />
* Usability enhancements, GUI fixes and internal optimizations.</p>
<p><strong>Bug fixes:</strong><br />
* MONyog was not working while behind Apache configured as a reverse proxy. This bug was introduced in MONyog 5.0.</p>
<p><strong>Downloads:</strong> <a href="http://webyog.com/en/downloads.php">http://webyog.com/en/downloads.php</a><br />
<strong>Purchase:</strong> <a href="http://webyog.com/en/buy.php">http://webyog.com/en/buy.php</a></p>

<!-- This is the start of the WP Twitter Button code -->
<div><a href="http://twitter.com/share" data-url="http://www.webyog.com/blog/2012/05/09/monyog-mysql-monitor-5-2-has-been-released/" data-count="horizontal" data-via="webyog">Tweet</a></div>
<!-- This is the end of the WP Twitter Button code --><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33169&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33169&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 12:43:52 +0000</pubDate>
    <dc:creator>Webyog</dc:creator>
    <category>MONyog</category>
    <category>MySQL</category>
    <category>Releases</category>
  </item>

  <item>
    <title>Simple and efficient MongoDB Backup using script</title>
    <guid isPermaLink="false">http://linuxadminzone.com/?p=511</guid>
    <link>http://feedproxy.google.com/~r/LinuxAdminZone/~3/cBWoPTq6CMo/</link>
    <description>MongoDB Backup types and strategies are neatly explained in its documentation, which you can check here. In case you are not familiar with MongoDB backup types and strategies, please have a look at its documentation.
What I am describing here is a simple script which we are using since months to take MongoDB backup and transfer it over to our Backup server. Here are few things its doing:

As we have multiple MongoDB Replica Sets, the script identify current replica set and check whether current server is Master or Slave, exit if its Master. We take backup only from Slave host.
Take Backup using mongodump command.
Upon successful completion of dump, transfer that to our Backup server. Ensure that ssh key based authentication is setup between both servers to implement seamless and secure transfer. It creates new directory based on current timestamp under replicaset directory in specified path at Backup server and transfer dump there.
Log each steps described above, send alert mail if any step fail with description or send confirmation mail upon successful execution with essential details.
Sample confirmation mail is below:


Subject: Backup for  done on  at 09/May/12 08:00:01 AM
Body: Mongo Backup Status for  on 09/May/12 08:00:01 AM. 
&amp;nbsp;
08:00:01 AM:  is slave and looks OK.
08:00:01 AM: Starting Dump, executing /usr/local/mongodb/mongo/bin/mongodump --out /databases/dump --host ...
08:34:06 AM: Mongodump command completed. Backup size is 25G. 
08:34:10 AM: Directory created on backup server, copying data using scp...
08:57:00 AM: Copied dump to backup server in directory /home/backup/Mongodump/replicaset/datestamp/.
08:57:00 AM: Mongo Backup process completed successfully.

Here is the full bash script, please note that you need to update variables properly and have to check and update it to run in your environment which can be entirely different from mine. Its just an idea to automate MongoDB backup:

##
# Script to take mongo backup using mongodump and store it in Backup Server
##
&amp;nbsp;
#!/bin/bash
&amp;nbsp;
## Set variables
TodayDate=`date +&amp;quot;%d/%b/%g %r&amp;quot;`
DateStamp=`date +%d%m%y%H%M%S`
CurrentTime=`date +&amp;quot;%r&amp;quot;`
&amp;nbsp;
MongoBinPath=&amp;quot;/usr/local/mongodb/mongo/bin&amp;quot;
ReplicaSet=`echo 'rs.status()' | $MongoBinPath/mongo | egrep &amp;quot;set&amp;quot; | awk -F \&amp;quot; '{print $4}'`
MongoHost=`hostname`
LocalBackupPath=&amp;quot;/databases/dump&amp;quot;
&amp;nbsp;
LogFile=&amp;quot;/var/log/mongo-backup.log&amp;quot;
IsOK=0
CmdStatus=&amp;quot;&amp;quot;
&amp;nbsp;
BackupHost=xx.xx.xx.xx
BackupHostPath=&amp;quot;/home/backup/mongobackup&amp;quot;
BackupHostPort=22
&amp;nbsp;
MailNotification=&amp;quot;admin@domain.com anotheradmin@domain.com&amp;quot;
&amp;nbsp;
echo -e &amp;quot;Mongo Backup Status for $ReplicaSet on $TodayDate. \n&amp;quot; &amp;amp;gt; $LogFile
&amp;nbsp;
## Check whether host is slave and in good state for backup
for i in `echo &amp;quot;rs.status()&amp;quot; | $MongoBinPath/mongo | egrep &amp;quot;name&amp;quot; | awk -F \&amp;quot; '{print $4}'| cut -f 1 -d :`; do
 IsMaster=`echo &amp;quot;db.isMaster()&amp;quot;| $MongoBinPath/mongo --host $i | grep ismaster|awk -F &amp;quot;:&amp;quot; '{print $2}' | cut -f 1 -d ,`;
 TheState=`echo &amp;quot;rs.status()&amp;quot;| $MongoBinPath/mongo --host $i | grep -i mystate | awk -F &amp;quot;:&amp;quot; '{print $2}' | cut -f 1 -d ,`;
 if &amp;#91; $IsMaster == &amp;quot;false&amp;quot; -a $TheState -eq 2  &amp;#93;; then
  MongoHost=$i
  IsOK=1
  echo &amp;quot;$CurrentTime: $MongoHost is slave and looks OK.&amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
  break
 fi
done
&amp;nbsp;
CurrentTime=`date +&amp;quot;%r&amp;quot;`
&amp;nbsp;
## Exit if not good
if &amp;#91; $IsOK -eq 0 &amp;#93;; then
   echo &amp;quot;$CurrentTime: Error: Either $MongoHost is not slave or not in good state. Aborting Backup, Please check!&amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
   mail -s &amp;quot;Backup error for $ReplicaSet from $MongoHost on $TodayDate&amp;quot; $MailNotification &amp;amp;lt; $LogFile    exit 1; fi ## Remove earlier backup CmdStatus=$(rm -rf $LocalBackupPath/*) ## Start backup process echo &amp;quot;$CurrentTime: Starting Dump, executing $MongoBinPath/mongodump --out $LocalBackupPath --host $MongoHost...&amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
&amp;nbsp;
CmdStatus=`$MongoBinPath/mongodump --out $LocalBackupPath --host $MongoHost`
if &amp;#91; $? -ne 0 &amp;#93;; then
  echo &amp;quot;$CurrentTime: There is an issue while trying to take dump in $MongoHost. Aborting dump process, please check! &amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
  cat $CmdStatus &amp;amp;gt;&amp;amp;gt; $LogFile
  mail -s &amp;quot;Backup error for $ReplicaSet from $MongoHost on $TodayDate&amp;quot; $MailNotification &amp;amp;lt; $LogFile   exit fi CurrentTime=`date +&amp;quot;%r&amp;quot;` BackupSize=$&amp;#40;du -sh $LocalBackupPath/. | awk '{ print $1 }'&amp;#41; echo &amp;quot;$CurrentTime: Mongodump command completed. Backup size is $BackupSize. &amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
&amp;nbsp;
## dump is fine then scp it to backup server
## create directory first
CmdStatus=$&amp;#40;ssh -p $BackupHostPort $BackupHost &amp;quot;mkdir -p  $BackupHostPath/$ReplicaSet/$DateStamp&amp;quot;&amp;#41;
&amp;nbsp;
if &amp;#91; $? -ne 0 &amp;#93;; then
  echo &amp;quot;$CurrentTime: Either failing to connect Backup server using ssh or destination directory already exist!&amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
  cat $CmdStatus &amp;amp;gt;&amp;amp;gt; $LogFile
  mail -s &amp;quot;Backup error for $ReplicaSet from $MongoHost on $TodayDate&amp;quot; $MailNotification &amp;amp;lt; $LogFile   exit fi CurrentTime=`date +&amp;quot;%r&amp;quot;` echo &amp;quot;$CurrentTime: Directory created on backup server, copying data using scp...&amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
&amp;nbsp;
CmdStatus=`scp -P $BackupHostPort -r $LocalBackupPath/* $BackupHost:/$BackupHostPath/$ReplicaSet/$DateStamp/`
if &amp;#91; $? -ne 0 &amp;#93;; then
  echo &amp;quot;$CurrentTime: Unable to scp dump to $BackupHost:/$BackupHostPath/$ReplicaSet/$DateStamp using port $BackupHostPort. &amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
  cat $CmdStatus &amp;amp;gt;&amp;amp;gt; $LogFile
  mail -s &amp;quot;Backup error for $ReplicaSet from $MongoHost on $TodayDate&amp;quot; $MailNotification &amp;amp;lt; $LogFile   exit fi CurrentTime=`date +&amp;quot;%r&amp;quot;` echo &amp;quot;$CurrentTime: Copied dump to backup server in directory $BackupHost$BackupHostPath/$ReplicaSet/$DateStamp/.&amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
echo &amp;quot;$CurrentTime: Mongo Backup process completed successfully.&amp;quot; &amp;amp;gt;&amp;amp;gt; $LogFile
mail -s &amp;quot;Backup for $ReplicaSet done on $MongoHost at $TodayDate&amp;quot; $MailRecipients $MailNotification &amp;amp;lt; $LogFile

Its just a basic script and may needs further enhancements. In case you have suggestion/queries, please put it below in comments.
More Related and helpful articles:

 Setup multiple MySQL database servers in a single Linux host
Optimize MySQL on a large Database Server 
Recover or reset root password of MySQL and PostgreSQL Servers 
 Optimize and fix MySQL Server running slow without any load 
 How to find out the clients connecting to your MySQL server 
 Quickly repair huge corrupted or crashed table in MySQL 
 Install and configure PhpMyAdmin to manage multiple MySQL Servers 

&amp;nbsp;

   
</description>
    <content:encoded><![CDATA[<p>MongoDB Backup types and strategies are neatly explained in its documentation, which you can check <a href="http://www.mongodb.org/display/DOCS/Backups" target="_blank">here</a>. In case you are not familiar with MongoDB backup types and strategies, please have a look at its documentation.</p>
<p>What I am describing here is a simple script which we are using since months to take MongoDB backup and transfer it over to our Backup server. Here are few things its doing:</p>
<ul>
<li>As we have multiple MongoDB Replica Sets, the script identify current replica set and check whether current server is Master or Slave, exit if its Master. We take backup only from Slave host.</li>
<li>Take Backup using mongodump command.</li>
<li>Upon successful completion of dump, transfer that to our Backup server. Ensure that ssh key based authentication is setup between both servers to implement seamless and secure transfer. It creates new directory based on current timestamp under replicaset directory in specified path at Backup server and transfer dump there.</li>
<li>Log each steps described above, send alert mail if any step fail with description or send confirmation mail upon successful execution with essential details.</li>
<li>Sample confirmation mail is below:</li>
</ul>

<div><div><pre>Subject: Backup <span>for</span>  <span>done</span> on  at 09<span>/</span>May<span>/</span><span>12</span> 08:00:01 AM
Body: Mongo Backup Status <span>for</span>  on 09<span>/</span>May<span>/</span><span>12</span> 08:00:01 AM. 
&nbsp;
08:00:01 AM:  is slave and looks OK.
08:00:01 AM: Starting Dump, executing <span>/</span>usr<span>/</span>local<span>/</span>mongodb<span>/</span>mongo<span>/</span>bin<span>/</span>mongodump <span>--out</span> <span>/</span>databases<span>/</span>dump <span>--host</span> ...
08:<span>34</span>:06 AM: Mongodump <span>command</span> completed. Backup <span>size</span> is 25G. 
08:<span>34</span>:<span>10</span> AM: Directory created on backup server, copying data using scp...
08:<span>57</span>:00 AM: Copied dump to backup server <span>in</span> directory <span>/</span>home<span>/</span>backup<span>/</span>Mongodump<span>/</span>replicaset<span>/</span>datestamp<span>/</span>.
08:<span>57</span>:00 AM: Mongo Backup process completed successfully.</pre></div></div>

<p>Here is the full bash script, please note that you need to update variables properly and have to check and update it to run in your environment which can be entirely different from mine. Its just an idea to automate MongoDB backup:</p>

<div><div><pre><span>##</span>
<span># Script to take mongo backup using mongodump and store it in Backup Server</span>
<span>##</span>
&nbsp;
<span>#!/bin/bash</span>
&nbsp;
<span>## Set variables</span>
<span>TodayDate</span>=<span>`</span><span>date</span> +<span>&quot;%d/%b/%g %r&quot;</span><span>`</span>
<span>DateStamp</span>=<span>`</span><span>date</span> +<span>%</span>d<span>%</span>m<span>%</span>y<span>%</span>H<span>%</span>M<span>%</span>S<span>`</span>
<span>CurrentTime</span>=<span>`</span><span>date</span> +<span>&quot;%r&quot;</span><span>`</span>
&nbsp;
<span>MongoBinPath</span>=<span>&quot;/usr/local/mongodb/mongo/bin&quot;</span>
<span>ReplicaSet</span>=<span>`</span><span>echo</span> <span>'rs.status()'</span> <span>|</span> <span>$MongoBinPath</span><span>/</span>mongo <span>|</span> <span>egrep</span> <span>&quot;set&quot;</span> <span>|</span> <span>awk</span> <span>-F</span> <span>\&quot;</span> <span>'{print $4}'</span><span>`</span>
<span>MongoHost</span>=<span>`</span><span>hostname</span><span>`</span>
<span>LocalBackupPath</span>=<span>&quot;/databases/dump&quot;</span>
&nbsp;
<span>LogFile</span>=<span>&quot;/var/log/mongo-backup.log&quot;</span>
<span>IsOK</span>=<span>0</span>
<span>CmdStatus</span>=<span>&quot;&quot;</span>
&nbsp;
<span>BackupHost</span>=xx.xx.xx.xx
<span>BackupHostPath</span>=<span>&quot;/home/backup/mongobackup&quot;</span>
<span>BackupHostPort</span>=<span>22</span>
&nbsp;
<span>MailNotification</span>=<span>&quot;admin@domain.com anotheradmin@domain.com&quot;</span>
&nbsp;
<span>echo</span> <span>-e</span> <span>&quot;Mongo Backup Status for <span>$ReplicaSet</span> on <span>$TodayDate</span>. <span>\n</span>&quot;</span> <span>&amp;</span>gt; <span>$LogFile</span>
&nbsp;
<span>## Check whether host is slave and in good state for backup</span>
<span>for</span> i <span>in</span> <span>`</span><span>echo</span> <span>&quot;rs.status()&quot;</span> <span>|</span> <span>$MongoBinPath</span><span>/</span>mongo <span>|</span> <span>egrep</span> <span>&quot;name&quot;</span> <span>|</span> <span>awk</span> <span>-F</span> <span>\&quot;</span> <span>'{print $4}'</span><span>|</span> <span>cut</span> <span>-f</span> <span>1</span> <span>-d</span> :<span>`</span>; <span>do</span>
 <span>IsMaster</span>=<span>`</span><span>echo</span> <span>&quot;db.isMaster()&quot;</span><span>|</span> <span>$MongoBinPath</span><span>/</span>mongo <span>--host</span> <span>$i</span> <span>|</span> <span>grep</span> ismaster<span>|</span><span>awk</span> <span>-F</span> <span>&quot;:&quot;</span> <span>'{print $2}'</span> <span>|</span> <span>cut</span> <span>-f</span> <span>1</span> <span>-d</span> ,<span>`</span>;
 <span>TheState</span>=<span>`</span><span>echo</span> <span>&quot;rs.status()&quot;</span><span>|</span> <span>$MongoBinPath</span><span>/</span>mongo <span>--host</span> <span>$i</span> <span>|</span> <span>grep</span> <span>-i</span> mystate <span>|</span> <span>awk</span> <span>-F</span> <span>&quot;:&quot;</span> <span>'{print $2}'</span> <span>|</span> <span>cut</span> <span>-f</span> <span>1</span> <span>-d</span> ,<span>`</span>;
 <span>if</span> <span>&#91;</span> <span>$IsMaster</span> == <span>&quot;false&quot;</span> <span>-a</span> <span>$TheState</span> <span>-eq</span> <span>2</span>  <span>&#93;</span>; <span>then</span>
  <span>MongoHost</span>=<span>$i</span>
  <span>IsOK</span>=<span>1</span>
  <span>echo</span> <span>&quot;<span>$CurrentTime</span>: <span>$MongoHost</span> is slave and looks OK.&quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
  <span>break</span>
 <span>fi</span>
<span>done</span>
&nbsp;
<span>CurrentTime</span>=<span>`</span><span>date</span> +<span>&quot;%r&quot;</span><span>`</span>
&nbsp;
<span>## Exit if not good</span>
<span>if</span> <span>&#91;</span> <span>$IsOK</span> <span>-eq</span> <span>0</span> <span>&#93;</span>; <span>then</span>
   <span>echo</span> <span>&quot;<span>$CurrentTime</span>: Error: Either <span>$MongoHost</span> is not slave or not in good state. Aborting Backup, Please check!&quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
   mail <span>-s</span> <span>&quot;Backup error for <span>$ReplicaSet</span> from <span>$MongoHost</span> on <span>$TodayDate</span>&quot;</span> <span>$MailNotification</span> <span>&amp;</span>lt; <span>$LogFile</span>    <span>exit</span> <span>1</span>; <span>fi</span> <span>## Remove earlier backup CmdStatus=$(rm -rf $LocalBackupPath/*) ## Start backup process echo &quot;$CurrentTime: Starting Dump, executing $MongoBinPath/mongodump --out $LocalBackupPath --host $MongoHost...&quot; &amp;gt;&amp;gt; $LogFile</span>
&nbsp;
<span>CmdStatus</span>=<span>`</span><span>$MongoBinPath</span><span>/</span>mongodump <span>--out</span> <span>$LocalBackupPath</span> <span>--host</span> <span>$MongoHost</span><span>`</span>
<span>if</span> <span>&#91;</span> <span>$?</span> <span>-ne</span> <span>0</span> <span>&#93;</span>; <span>then</span>
  <span>echo</span> <span>&quot;<span>$CurrentTime</span>: There is an issue while trying to take dump in <span>$MongoHost</span>. Aborting dump process, please check! &quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
  <span>cat</span> <span>$CmdStatus</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
  mail <span>-s</span> <span>&quot;Backup error for <span>$ReplicaSet</span> from <span>$MongoHost</span> on <span>$TodayDate</span>&quot;</span> <span>$MailNotification</span> <span>&amp;</span>lt; <span>$LogFile</span>   <span>exit</span> <span>fi</span> <span>CurrentTime</span>=<span>`</span><span>date</span> +<span>&quot;%r&quot;</span><span>`</span> <span>BackupSize</span>=$<span>&#40;</span><span>du</span> <span>-sh</span> <span>$LocalBackupPath</span><span>/</span>. <span>|</span> <span>awk</span> <span>'{ print $1 }'</span><span>&#41;</span> <span>echo</span> <span>&quot;<span>$CurrentTime</span>: Mongodump command completed. Backup size is <span>$BackupSize</span>. &quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
&nbsp;
<span>## dump is fine then scp it to backup server</span>
<span>## create directory first</span>
<span>CmdStatus</span>=$<span>&#40;</span><span>ssh</span> <span>-p</span> <span>$BackupHostPort</span> <span>$BackupHost</span> <span>&quot;mkdir -p  <span>$BackupHostPath</span>/<span>$ReplicaSet</span>/<span>$DateStamp</span>&quot;</span><span>&#41;</span>
&nbsp;
<span>if</span> <span>&#91;</span> <span>$?</span> <span>-ne</span> <span>0</span> <span>&#93;</span>; <span>then</span>
  <span>echo</span> <span>&quot;<span>$CurrentTime</span>: Either failing to connect Backup server using ssh or destination directory already exist!&quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
  <span>cat</span> <span>$CmdStatus</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
  mail <span>-s</span> <span>&quot;Backup error for <span>$ReplicaSet</span> from <span>$MongoHost</span> on <span>$TodayDate</span>&quot;</span> <span>$MailNotification</span> <span>&amp;</span>lt; <span>$LogFile</span>   <span>exit</span> <span>fi</span> <span>CurrentTime</span>=<span>`</span><span>date</span> +<span>&quot;%r&quot;</span><span>`</span> <span>echo</span> <span>&quot;<span>$CurrentTime</span>: Directory created on backup server, copying data using scp...&quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
&nbsp;
<span>CmdStatus</span>=<span>`</span><span>scp</span> <span>-P</span> <span>$BackupHostPort</span> <span>-r</span> <span>$LocalBackupPath</span><span>/*</span> <span>$BackupHost</span>:<span>/</span><span>$BackupHostPath</span><span>/</span><span>$ReplicaSet</span><span>/</span><span>$DateStamp</span><span>/`</span>
<span>if</span> <span>&#91;</span> <span>$?</span> <span>-ne</span> <span>0</span> <span>&#93;</span>; <span>then</span>
  <span>echo</span> <span>&quot;<span>$CurrentTime</span>: Unable to scp dump to <span>$BackupHost</span>:/<span>$BackupHostPath</span>/<span>$ReplicaSet</span>/<span>$DateStamp</span> using port <span>$BackupHostPort</span>. &quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
  <span>cat</span> <span>$CmdStatus</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
  mail <span>-s</span> <span>&quot;Backup error for <span>$ReplicaSet</span> from <span>$MongoHost</span> on <span>$TodayDate</span>&quot;</span> <span>$MailNotification</span> <span>&amp;</span>lt; <span>$LogFile</span>   <span>exit</span> <span>fi</span> <span>CurrentTime</span>=<span>`</span><span>date</span> +<span>&quot;%r&quot;</span><span>`</span> <span>echo</span> <span>&quot;<span>$CurrentTime</span>: Copied dump to backup server in directory <span>$BackupHost</span><span>$BackupHostPath</span>/<span>$ReplicaSet</span>/<span>$DateStamp</span>/.&quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
<span>echo</span> <span>&quot;<span>$CurrentTime</span>: Mongo Backup process completed successfully.&quot;</span> <span>&amp;</span>gt;<span>&amp;</span>gt; <span>$LogFile</span>
mail <span>-s</span> <span>&quot;Backup for <span>$ReplicaSet</span> done on <span>$MongoHost</span> at <span>$TodayDate</span>&quot;</span> <span>$MailRecipients</span> <span>$MailNotification</span> <span>&amp;</span>lt; <span>$LogFile</span></pre></div></div>

<p>Its just a basic script and may needs further enhancements. In case you have suggestion/queries, please put it below in comments.</p>
<p><span>More Related and helpful articles:</span></p>
<ul>
<li><a href="http://linuxadminzone.com/optimize-mysql-on-a-large-database-server/"> Setup multiple MySQL database servers in a single Linux host</a></li>
<li><a href="http://linuxadminzone.com/optimize-mysql-on-a-large-database-server/">Optimize MySQL on a large Database Server </a></li>
<li><a href="http://linuxadminzone.com/recover-or-reset-root-password-of-mysql-and-postgresql-servers/">Recover or reset root password of MySQL and PostgreSQL Servers </a></li>
<li><a href="http://linuxadminzone.com/optimize-and-fix-mysql-server-running-slow-without-any-load/"> Optimize and fix MySQL Server running slow without any load </a></li>
<li><a href="http://linuxadminzone.com/find-out-the-clients-of-your-mysql-server/"> How to find out the clients connecting to your MySQL server </a></li>
<li><a href="http://linuxadminzone.com/quickly-repair-a-huge-corrupted-or-crashed-table-in-mysql/"> Quickly repair huge corrupted or crashed table in MySQL </a></li>
<li><a href="http://linuxadminzone.com/install-and-configure-phpmyadmin-to-manage-multiple-mysql-servers/"> Install and configure PhpMyAdmin to manage multiple MySQL Servers </a></li>
</ul>
<p>&nbsp;</p>
<div>
<a href="http://feeds.feedburner.com/~ff/LinuxAdminZone?a=cBWoPTq6CMo:WCWSrFL6_8A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LinuxAdminZone?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LinuxAdminZone?a=cBWoPTq6CMo:WCWSrFL6_8A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LinuxAdminZone?i=cBWoPTq6CMo:WCWSrFL6_8A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LinuxAdminZone?a=cBWoPTq6CMo:WCWSrFL6_8A:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/LinuxAdminZone?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LinuxAdminZone?a=cBWoPTq6CMo:WCWSrFL6_8A:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/LinuxAdminZone?i=cBWoPTq6CMo:WCWSrFL6_8A:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/LinuxAdminZone/~4/cBWoPTq6CMo" height="1" width="1" /><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33183&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33183&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 10:17:54 +0000</pubDate>
    <dc:creator>Jagbir Singh</dc:creator>
    <category>database</category>
    <category>nosql</category>
    <category>bash</category>
    <category>mongodb</category>
    <category>mongodump</category>
    <category>script</category>
  </item>

  <item>
    <title>Hopper for Firebird, 1.0 released</title>
    <guid isPermaLink="false">4EA8D7E7-1442-48AE-A1A0-3BB065F0522E</guid>
    <link>http://www.upscene.com/displaynews.php?item=20120509</link>
    <description>Hopper for Firebird, 1.0 released 
[2012-05-09]

Upscene Productions is proud to announce the first release of our new product &quot;Hopper&quot;, a Stored Code Debugger for Firebird.

Thanks to the feedback of people who downloaded the betas, we were able to improve Hopper.

Hopper is currently available for Firebird, the InterBase and MySQL Editions will follow shortly.

More information available at the Hopper page, download your copy today via our downloads page, pricing information is available.</description>
    <content:encoded><![CDATA[<b>Hopper for Firebird, 1.0 released </b><br />
[2012-05-09]<br />
<br />
Upscene Productions is proud to announce the first release of our new product "Hopper", a Stored Code Debugger for Firebird.<br />
<br />
Thanks to the feedback of people who downloaded the betas, we were able to improve Hopper.<br />
<br />
Hopper is currently available for Firebird, the InterBase and MySQL Editions will follow shortly.<br />
<br />
More information available at the <a href="http://www.upscene.com/go/?go=hopper" target="_blank">Hopper page</a>, download your copy today via our <a href="http://www.upscene.com/go/?go=download" target="_blank">downloads page</a>, <a href="http://www.upscene.com/go/?go=purchase" target="_blank">pricing information</a> is available.<br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33180&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33180&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 07:26:55 +0000</pubDate>
    <dc:creator>Martijn Tonies</dc:creator>
  </item>

  <item>
    <title>Percona Live MySQL Conference</title>
    <guid isPermaLink="false">http://ebergen.net/wordpress/?p=568</guid>
    <link>http://ebergen.net/wordpress/2012/05/08/percona-live-mysql-conference/</link>
    <description>These are things I like that I consider differences from last years conference. There are plenty of other things I like that don&amp;#8217;t need to be listed here.

The overall tone and feel of the conference was much less marking and much more technical
Refreshingly honest keynotes. There was a lot of coming clean about the history of MySQL and the conference.
Percona is very technical but it is also a business. They are very good about bringing out the technical and not being pushy about the business.
No ice cream social. A thousand people shaking sticky hands with each other is never a good idea.
percona.tv
The conference was busy but never crowded

Now for the dislike:

Only one song before every session.
The chairs. Damn the chairs.
Wifi failed more often than it worked. Most of the time I was tethered to my phone.
smartcity doesn&amp;#8217;t work with ssh port forwarded dns/socks poor man vpn.

Just some things to note and tips for next year

Classic rock bump in music for the keynotes didn&amp;#8217;t really fit.
Percona folks are usually really good about having information in the slides. So if you have to choose between skipping a Percona talk for some other talk skip the Percona one because you can go back and read the slides.
There is a secret clean bathroom that usually stays clean until the last day. I&amp;#8217;m not saying where this is.
Monty&amp;#8217;s BoF always has black vodka.
The black vodka is dangerous so be careful.

I was tempted to skip the conference this year because last year was so depressing. I decided to give Percona a chance at hosting it and I&amp;#8217;m glad I did. I look forward to attending and maybe presenting next year.</description>
    <content:encoded><![CDATA[<p>These are things I like that I consider differences from last years conference. There are plenty of other things I like that don&#8217;t need to be listed here.</p>
<ul>
<li>The overall tone and feel of the conference was much less marking and much more technical</li>
<li>Refreshingly honest keynotes. There was a lot of coming clean about the history of MySQL and the conference.</li>
<li>Percona is very technical but it is also a business. They are very good about bringing out the technical and not being pushy about the business.</li>
<li>No ice cream social. A thousand people shaking sticky hands with each other is never a good idea.</li>
<li>percona.tv</li>
<li>The conference was busy but never crowded</li>
</ul>
<p>Now for the dislike:</p>
<ul>
<li>Only one song before every session.</li>
<li>The chairs. Damn the chairs.</li>
<li>Wifi failed more often than it worked. Most of the time I was tethered to my phone.</li>
<li>smartcity doesn&#8217;t work with ssh port forwarded dns/socks poor man vpn.</li>
</ul>
<p>Just some things to note and tips for next year</p>
<ul>
<li>Classic rock bump in music for the keynotes didn&#8217;t really fit.</li>
<li>Percona folks are usually really good about having information in the slides. So if you have to choose between skipping a Percona talk for some other talk skip the Percona one because you can go back and read the slides.</li>
<li>There is a secret clean bathroom that usually stays clean until the last day. I&#8217;m not saying where this is.</li>
<li>Monty&#8217;s BoF always has black vodka.</li>
<li>The black vodka is dangerous so be careful.</li>
</ul>
<p>I was tempted to skip the conference this year because last year was so depressing. I decided to give Percona a chance at hosting it and I&#8217;m glad I did. I look forward to attending and maybe presenting next year.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33168&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33168&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 03:47:25 +0000</pubDate>
    <dc:creator>Eric Bergen</dc:creator>
    <category>Geek</category>
    <category>MariaDB</category>
    <category>MySQL</category>
  </item>

  <item>
    <title>MySQL 5.0 can deadlock when flush logs, show processlist, and a slave connection happen at the same time</title>
    <guid isPermaLink="false">http://ebergen.net/wordpress/?p=545</guid>
    <link>http://ebergen.net/wordpress/2012/05/08/mysql-5-0-can-deadlock-when-flush-logs-show-processlist-and-a-slave-connection-happen-at-the-same-time/</link>
    <description>[ Note: I haven't fully investigated this problem but the post has been hanging around in my queue for months. Rather than have it rot there I am publishing what I know in hopes that it helps someone else. ]
There are a lot of different kinds of locks in MySQL. Some of these locks are exposed to users such as intention locks, table locks, and row locks. There are other locks that aren&amp;#8217;t exposed as well. These are mutexes that MySQL uses internally to protect resources from being modified by more than one thread at a time. These locks are numerous and complicated. When these locks deadlock mysql can stop dead in it&amp;#8217;s tracks. The last deadlock I found happens when flush logs, show processlist, and a slave reconnect happen at the same time. I don&amp;#8217;t have a core from the mysqld process, only stack traces. The breakdowns of stack traces are locks that I&amp;#8217;m pretty sure the threads own and ones that they may be stuck trying on. I am working on gathering more data and making a repeatable test case. I will update this post or link to a new one when I do.
Flush logs is responsible for rotating and deleting old logs. It rotates every log under the sun including the relay and binary logs. I created a patch a few years ago to allow users to specify which log to rotate that is now included in MySQL 5.5. Flush logs has a safe guard built in when flushing binary logs to a make sure that it isn&amp;#8217;t going to delete  a log that a binlog dump thread hasn&amp;#8217;t sent to a slave yet. For this safe guard to work it has to loop through every client thread in MySQL and check if it is a dump thread. If it is then it has to check which log it is on to make sure the log isn&amp;#8217;t in use.
Each log file has a few mutexes associated with it. The flush logs thread owns LOCK_log and LOCK_index from the binary log. bl in this case refers to the binary log object. linfo is the log info object which is part of the thread for some reason.
Owns locks
bl-&amp;gt;LOCK_log
bl-&amp;gt;LOCK_index
Tries to lock
LOCK_thread_count
linfo-&amp;gt;lock
Thread 11 (Thread 0x458e6940 (LWP 27068)):
#0 0x000000377560d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003775608e50 in _L_lock_1233 () from /lib64/libpthread.so.0
#2 0x0000003775608dd3 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x000000000066f8f6 in log_in_use(char const*) () &amp;lt;&amp;#8211; LOCK_thread_count
#4 0x00000000005f88d0 in MYSQL_LOG::purge_logs_before_date(long) () &amp;lt;&amp;#8211; gets bl-&amp;gt;LOCK_index
#5 0x00000000005fa09c in MYSQL_LOG::rotate_and_purge(unsigned int) () &amp;lt;&amp;#8211; gets bl-&amp;gt;LOCK_log
#6 0x000000000058715d in reload_acl_and_cache(THD*, unsigned long, TABLE_LIST*, bool*) ()
#7 0x000000000058c3d3 in mysql_execute_command(THD*) ()
#8 0x00000000005915f1 in mysql_parse(THD*, char const*, unsigned int, char const**) ()
#9 0x000000000059279e in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()
#10 0x000000000059374b in handle_one_connection ()
#11 0x000000377560673d in start_thread () from /lib64/libpthread.so.0
#12 0x0000003774ad3d1d in clone () from /lib64/libc.so.6
&amp;nbsp;
What I mean by slave connection is what happens on the master when a slave connects. The master will spawn a thread that is responsible for killing any other threads with the same server id and then sending binlogs to the slave. This is why when two slaves are configured with the same server id they will disconnect each other. Slaves will try to reconnect a minute later by default 60 seconds. So every minute each slave will get to download binlogs for a minute. The important part for this deadlock is that when a new slave connects the thread spawned by the master will walk through every thread connected to MySQL looking for an old thread with the same slave server id and try to kill it.
This is the stack from the new slave thread trying to kill the old one
Owns
tmp-&amp;gt;LOCK_delete from thread 16.
16-&amp;gt;mysys_var-&amp;gt;mutex
Tries
bl-&amp;gt;LOCK_log from thread 16-&amp;gt;mysys_var-&amp;gt;current_mutex
Thread 17 (Thread 0&amp;#215;45968940 (LWP 27194)):
#0 0x000000377560d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003775608e1a in _L_lock_1034 () from /lib64/libpthread.so.0
#2 0x0000003775608cdc in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x000000000056863f in THD::awake(THD::killed_state) ()
#4 0x000000000066f8a3 in kill_zombie_dump_threads(unsigned int) ()
#5 0x0000000000592a6e in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()
#6 0x000000000059374b in handle_one_connection ()
#7 0x000000377560673d in start_thread () from /lib64/libpthread.so.0
#8 0x0000003774ad3d1d in clone () from /lib64/libc.so.6
The current_mutex deserves a bit of explanation here. In MySQL when a thread wants to wait on a condition it copies the mutex and condition into mysys_var-&amp;gt;current_mutex and mysys_var-&amp;gt;current_cond. The mysys_var-&amp;gt;mutex is the mutex that protects the mysys_var struct. This way if any other thread needs to kill it it knows the condition and mutex it is waiting on so it can be woken up. This is an easy mechanism to kill threads but it makes it more difficult to figure out what a thread is locking on. In this case I think current_mutex is bl-&amp;gt;LOCK_log from thread 16 which is coming up.
Thread 16 (Thread 0x45aee940 (LWP 3819)):
#0 0x000000377560d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00000037756101b1 in _L_cond_lock_989 () from /lib64/libpthread.so.0
#2 0x000000377561007f in __pthread_mutex_cond_lock () from /lib64/libpthread.so.0
#3 0x000000377560af84 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#4 0x00000000005f6637 in MYSQL_LOG::wait_for_update(THD*, bool) ()
#5 0x000000000067133a in mysql_binlog_send(THD*, char*, unsigned long long, unsigned short) ()
#6 0&amp;#215;0000000000592639 in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()
#7 0x000000000059374b in handle_one_connection ()
#8 0x000000377560673d in start_thread () from /lib64/libpthread.so.0
#9 0x0000003774ad3d1d in clone () from /lib64/libc.so.6
Thread 16 is the old master thread waiting to dump a binglog. It should be killed by the new thread but isn&amp;#8217;t.
Show processlist also loop through the list of client threads to get their id, hostname, user, state and query that they may be running. The common theme between all of these threads is that they all need to loop through the list of client threads in order to do their jobs. When looping through this list they must grab the LOCK_thread_count mutex. Owning this mutex means that no other thread will be able to change the list of client threads making it safe to loop through.
Owns
LOCK_thread_count
Tries
mysys_var-&amp;gt;mutex probably from thread 16/17
Thread 3 (Thread 0x45a6c940 (LWP 13482)):
#0 0x000000377560d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003775608e50 in _L_lock_1233 () from /lib64/libpthread.so.0
#2 0x0000003775608dd3 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x000000000065879a in mysqld_list_processes(THD*, char const*, bool) ()
#4 0x000000000058ecf6 in mysql_execute_command(THD*) ()
#5 0x00000000005915f1 in mysql_parse(THD*, char const*, unsigned int, char const**) ()
#6 0x000000000059279e in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()
#7 0x000000000059374b in handle_one_connection ()
#8 0x000000377560673d in start_thread () from /lib64/libpthread.so.0
#9 0x0000003774ad3d1d in clone () from /lib64/libc.so.6
I haven&amp;#8217;t quite solved this one yet but I hope the breakdown may help someone else with the same issue. I worked around this one by disabling a script that runs show processlist and records this output. This makes it far less likely that all three conditions will be met to produce the deadlock. Other options are changing the log rotation script to only flush the logs it needs or figure out why the slave reconnect happens. I have a few theories on long running log rotations causing this but I haven&amp;#8217;t been able to reproduce them.</description>
    <content:encoded><![CDATA[<p>[ Note: I haven't fully investigated this problem but the post has been hanging around in my queue for months. Rather than have it rot there I am publishing what I know in hopes that it helps someone else. ]</p>
<p>There are a lot of different kinds of locks in MySQL. Some of these locks are exposed to users such as intention locks, table locks, and row locks. There are other locks that aren&#8217;t exposed as well. These are mutexes that MySQL uses internally to protect resources from being modified by more than one thread at a time. These locks are numerous and complicated. When these locks deadlock mysql can stop dead in it&#8217;s tracks. The last deadlock I found happens when flush logs, show processlist, and a slave reconnect happen at the same time. I don&#8217;t have a core from the mysqld process, only stack traces. The breakdowns of stack traces are locks that I&#8217;m pretty sure the threads own and ones that they may be stuck trying on. I am working on gathering more data and making a repeatable test case. I will update this post or link to a new one when I do.</p>
<p>Flush logs is responsible for rotating and deleting old logs. It rotates every log under the sun including the relay and binary logs. I created a patch a few years ago to allow users to specify which log to rotate that is now included in MySQL 5.5. Flush logs has a safe guard built in when flushing binary logs to a make sure that it isn&#8217;t going to delete  a log that a binlog dump thread hasn&#8217;t sent to a slave yet. For this safe guard to work it has to loop through every client thread in MySQL and check if it is a dump thread. If it is then it has to check which log it is on to make sure the log isn&#8217;t in use.</p>
<p>Each log file has a few mutexes associated with it. The flush logs thread owns LOCK_log and LOCK_index from the binary log. bl in this case refers to the binary log object. linfo is the log info object which is part of the thread for some reason.</p>
<p>Owns locks<br />
bl-&gt;LOCK_log<br />
bl-&gt;LOCK_index<br />
Tries to lock<br />
LOCK_thread_count<br />
linfo-&gt;lock</p>
<blockquote><p>Thread 11 (Thread 0x458e6940 (LWP 27068)):<br />
#0 0x000000377560d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0<br />
#1 0x0000003775608e50 in _L_lock_1233 () from /lib64/libpthread.so.0<br />
#2 0x0000003775608dd3 in pthread_mutex_lock () from /lib64/libpthread.so.0<br />
#3 0x000000000066f8f6 in log_in_use(char const*) () &lt;&#8211; LOCK_thread_count<br />
#4 0x00000000005f88d0 in MYSQL_LOG::purge_logs_before_date(long) () &lt;&#8211; gets bl-&gt;LOCK_index<br />
#5 0x00000000005fa09c in MYSQL_LOG::rotate_and_purge(unsigned int) () &lt;&#8211; gets bl-&gt;LOCK_log<br />
#6 0x000000000058715d in reload_acl_and_cache(THD*, unsigned long, TABLE_LIST*, bool*) ()<br />
#7 0x000000000058c3d3 in mysql_execute_command(THD*) ()<br />
#8 0x00000000005915f1 in mysql_parse(THD*, char const*, unsigned int, char const**) ()<br />
#9 0x000000000059279e in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()<br />
#10 0x000000000059374b in handle_one_connection ()<br />
#11 0x000000377560673d in start_thread () from /lib64/libpthread.so.0<br />
#12 0x0000003774ad3d1d in clone () from /lib64/libc.so.6</p></blockquote>
<p>&nbsp;</p>
<p>What I mean by slave connection is what happens on the master when a slave connects. The master will spawn a thread that is responsible for killing any other threads with the same server id and then sending binlogs to the slave. This is why when two slaves are configured with the same server id they will disconnect each other. Slaves will try to reconnect a minute later by default 60 seconds. So every minute each slave will get to download binlogs for a minute. The important part for this deadlock is that when a new slave connects the thread spawned by the master will walk through every thread connected to MySQL looking for an old thread with the same slave server id and try to kill it.</p>
<p>This is the stack from the new slave thread trying to kill the old one</p>
<p>Owns<br />
tmp-&gt;LOCK_delete from thread 16.<br />
16-&gt;mysys_var-&gt;mutex<br />
Tries<br />
bl-&gt;LOCK_log from thread 16-&gt;mysys_var-&gt;current_mutex</p>
<blockquote><p>Thread 17 (Thread 0&#215;45968940 (LWP 27194)):<br />
#0 0x000000377560d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0<br />
#1 0x0000003775608e1a in _L_lock_1034 () from /lib64/libpthread.so.0<br />
#2 0x0000003775608cdc in pthread_mutex_lock () from /lib64/libpthread.so.0<br />
#3 0x000000000056863f in THD::awake(THD::killed_state) ()<br />
#4 0x000000000066f8a3 in kill_zombie_dump_threads(unsigned int) ()<br />
#5 0x0000000000592a6e in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()<br />
#6 0x000000000059374b in handle_one_connection ()<br />
#7 0x000000377560673d in start_thread () from /lib64/libpthread.so.0<br />
#8 0x0000003774ad3d1d in clone () from /lib64/libc.so.6</p></blockquote>
<p>The current_mutex deserves a bit of explanation here. In MySQL when a thread wants to wait on a condition it copies the mutex and condition into mysys_var-&gt;current_mutex and mysys_var-&gt;current_cond. The mysys_var-&gt;mutex is the mutex that protects the mysys_var struct. This way if any other thread needs to kill it it knows the condition and mutex it is waiting on so it can be woken up. This is an easy mechanism to kill threads but it makes it more difficult to figure out what a thread is locking on. In this case I think current_mutex is bl-&gt;LOCK_log from thread 16 which is coming up.</p>
<blockquote><p>Thread 16 (Thread 0x45aee940 (LWP 3819)):<br />
#0 0x000000377560d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0<br />
#1 0x00000037756101b1 in _L_cond_lock_989 () from /lib64/libpthread.so.0<br />
#2 0x000000377561007f in __pthread_mutex_cond_lock () from /lib64/libpthread.so.0<br />
#3 0x000000377560af84 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0<br />
#4 0x00000000005f6637 in MYSQL_LOG::wait_for_update(THD*, bool) ()<br />
#5 0x000000000067133a in mysql_binlog_send(THD*, char*, unsigned long long, unsigned short) ()<br />
#6 0&#215;0000000000592639 in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()<br />
#7 0x000000000059374b in handle_one_connection ()<br />
#8 0x000000377560673d in start_thread () from /lib64/libpthread.so.0<br />
#9 0x0000003774ad3d1d in clone () from /lib64/libc.so.6</p></blockquote>
<p>Thread 16 is the old master thread waiting to dump a binglog. It should be killed by the new thread but isn&#8217;t.</p>
<p>Show processlist also loop through the list of client threads to get their id, hostname, user, state and query that they may be running. The common theme between all of these threads is that they all need to loop through the list of client threads in order to do their jobs. When looping through this list they must grab the LOCK_thread_count mutex. Owning this mutex means that no other thread will be able to change the list of client threads making it safe to loop through.</p>
<p>Owns<br />
LOCK_thread_count<br />
Tries<br />
mysys_var-&gt;mutex probably from thread 16/17</p>
<blockquote><p>Thread 3 (Thread 0x45a6c940 (LWP 13482)):<br />
#0 0x000000377560d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0<br />
#1 0x0000003775608e50 in _L_lock_1233 () from /lib64/libpthread.so.0<br />
#2 0x0000003775608dd3 in pthread_mutex_lock () from /lib64/libpthread.so.0<br />
#3 0x000000000065879a in mysqld_list_processes(THD*, char const*, bool) ()<br />
#4 0x000000000058ecf6 in mysql_execute_command(THD*) ()<br />
#5 0x00000000005915f1 in mysql_parse(THD*, char const*, unsigned int, char const**) ()<br />
#6 0x000000000059279e in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()<br />
#7 0x000000000059374b in handle_one_connection ()<br />
#8 0x000000377560673d in start_thread () from /lib64/libpthread.so.0<br />
#9 0x0000003774ad3d1d in clone () from /lib64/libc.so.6</p></blockquote>
<p>I haven&#8217;t quite solved this one yet but I hope the breakdown may help someone else with the same issue. I worked around this one by disabling a script that runs show processlist and records this output. This makes it far less likely that all three conditions will be met to produce the deadlock. Other options are changing the log rotation script to only flush the logs it needs or figure out why the slave reconnect happens. I have a few theories on long running log rotations causing this but I haven&#8217;t been able to reproduce them.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33167&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=33167&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
    <pubDate>Wed, 09 May 2012 03:32:46 +0000</pubDate>
    <dc:creator>Eric Bergen</dc:creator>
    <category>Geek</category>
    <category>MySQL</category>
  </item>

</channel>
</rss>

