<?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>Fri, 03 Jul 2009 02:40:01 +0000</pubDate>
  <language>en</language>
  <description>Planet MySQL - http://www.planetmysql.org/</description>

  <item>
    <title>Onsite and Remote - getting best of both worlds</title>
    <guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=712</guid>
    <link>http://www.mysqlperformanceblog.com/2009/07/02/onsite-and-remote-getting-best-of-both-worlds/</link>
    <description>At Percona we provide services both Onsite - visiting the customers and Remote - logging in to their systems or communicating via email,phone,instant messaging.  
We believe both approaches have their benefits and drawbacks and mixing them right way allows you to get your problems solved most efficient way.
Onsite  visits are great as they allow consultant to meet your team in person and great for relationship building.  It is great for architecture design and review as you can sit down with the team and use drawing board. It also often allows the best focus both for consultant and for participating team - when consulting visit is arranged it is usually the top priority for some of the staff members which provide consultant with information and assistance he might need.  
Onsite visits also often allow to get prompt attention from other team - looking for network engineer to understand network topology or for someone from marketing to get the growth plans - they typically can be brought in for question. 
I believe Onsite visits also offer unmatched training experience for the team - one of the team members can work side by side with consultants observing what he does and asking the question about the progress.  
The Single Day visits are often extremely valuable as a kick off to do application redesign, for performance review or for starting long term Remote DBA or support relationships.  They can be done with little planning as basically for any system there is enough work to spend efficiently understanding the system and working on the pressing problems customer may have.    Such visits are often result in a lot of &amp;#8220;homework&amp;#8221; as application changes or implementing changes on production which when can benefit from remote followups to validate changes and provide further advice. 
Multi day onsite visits require a bit more planning to be efficient.   Many times in my career I would come to the customer for a week only to find I have created the implementation plan within 1-2 days and it will take a while to implement it and pass it through development and testing stages.    Before long onsite visit it is very good to have a call with consultant to understand what exactly needs to be done, how much time and what resources it requires.  
Projects which can be efficient as multi day visits are whenever implementation is required (coding unlike giving advice takes a lot of time) - migration projects, any forms of scripting,  implementation (writing queries), hands on setting up MySQL, Replication, Monitoring,  High Availability with MMM or DRBD are good examples.   
Another good example of efficient Multi-Day visit is when there are multiple groups or multiple applications using MySQL - in such case each of the problem areas/groups can gets its own day or few hours which keeps consultant busy.
To make a Multi-Day visit efficient it is important to plan on what will be done - what people will consultant need to work with and which problems do they have.   Providing proper access and having staging/test systems available are also often required.   
Remote   work has a benefit of consultant being available in the short time intervals and being able to multi task.  
Working with the customer there are two types of &amp;#8220;waits&amp;#8221; which are often encountered. First - waiting on the customer. It could be fixing access problems, completing application changes, QA,  scheduling downtime to implement changes and millions of other things.      Second - waiting on database (or other) operations to complete - backup, restore,  ALTER TABLE, load testing -  all of these things take time and make consultant to wait for them.   
In case you&amp;#8217;re working remotely consultant typically has other tasks to do while such long processes are  running.  If you&amp;#8217;re spending time onsite you may have other tasks or you may not while if you&amp;#8217;re working remotely there are always things to do.
Another benefit of remote work - it truly allows to engage the team.  If you have consultant onsite getting another one with some specific knowledge is complicated while getting another person to login to the system remotely for a quick look is easy and efficient.  
Time is another interesting factor - onsite visits usually happen during office hours while changes to production are often avoided.  With remote work it is much easier to do work which needs to be done at night hours. 
Remote work however also needs to be well organized.  The benefit of onsite work is - it is always planned at very specific time.  Given date and time consultant will be there so both consultant and customer prepare for the visit.  If appointment is just a phone call or online meeting there is larger chance it can be forgotten by ether party.    In many cases the remote work not planned to the specific time at all which can cause it to be delayed because of either party delays. 
If you need something to be done fast and you&amp;#8217;re doing it remotely make sure to plan it to exact time and make sure there is someone to assist consultant if he needs any help such as access issues,  some questions about setup or what exactly given queries are doing.  Prompt responses can keep the ball rolling much faster.
Another trick to make remote work successful is to be very clear in your instructions especially if you&amp;#8217;re not going to be available to assist consultant when he is doing the work.  As remote work is often done cross time zones this becomes a very important factor.
In case you have a lot of work done in such &amp;#8220;disconnected&amp;#8221; mode it is a good idea to have daily/weekly/or be-weekly  (depending on project intensity)  calls to get team to discuss the progress and generally get team on the same page.
In general surprisingly a lot of things can be done in completely remote mode - we&amp;#8217;ve done not only basic optimizations but architecture redesigns, large scale deployment, migrations and high available architectures implementation such a way often surprising customers (in a good way) of how little customers the work took. 
The Great Mix   As I mentioned before mixing Onsite and Remote work can be indeed the best mix especially for the complex projects.   Onsite visit is great to setup relationships, get initial understanding of the system and get initial project planning.  After it is done a lot of work can be done remotely quite efficient while there may be the benefit in onsite status-checks and team interactions as well.  
    
    Entry posted by peter |
      No comment
    Add to:  |  |  |  | </description>
    <content:encoded><![CDATA[<p>At <a href="http://www.percona.com">Percona</a> we provide services both Onsite - visiting the customers and Remote - logging in to their systems or communicating via email,phone,instant messaging.  </p>
<p>We believe both approaches have their benefits and drawbacks and mixing them right way allows you to get your problems solved most efficient way.</p>
<p><strong>Onsite</strong>  visits are great as they allow consultant to meet your team in person and great for relationship building.  It is great for architecture design and review as you can sit down with the team and use drawing board. It also often allows the best focus both for consultant and for participating team - when consulting visit is arranged it is usually the top priority for some of the staff members which provide consultant with information and assistance he might need.  </p>
<p>Onsite visits also often allow to get prompt attention from other team - looking for network engineer to understand network topology or for someone from marketing to get the growth plans - they typically can be brought in for question. </p>
<p>I believe Onsite visits also offer unmatched training experience for the team - one of the team members can work side by side with consultants observing what he does and asking the question about the progress.  </p>
<p>The Single Day visits are often extremely valuable as a kick off to do application redesign, for performance review or for starting long term Remote DBA or support relationships.  They can be done with little planning as basically for any system there is enough work to spend efficiently understanding the system and working on the pressing problems customer may have.    Such visits are often result in a lot of &#8220;homework&#8221; as application changes or implementing changes on production which when can benefit from remote followups to validate changes and provide further advice. </p>
<p>Multi day onsite visits require a bit more planning to be efficient.   Many times in my career I would come to the customer for a week only to find I have created the implementation plan within 1-2 days and it will take a while to implement it and pass it through development and testing stages.    Before long onsite visit it is very good to have a call with consultant to understand what exactly needs to be done, how much time and what resources it requires.  </p>
<p>Projects which can be efficient as multi day visits are whenever implementation is required (coding unlike giving advice takes a lot of time) - migration projects, any forms of scripting,  implementation (writing queries), hands on setting up MySQL, Replication, Monitoring,  High Availability with MMM or DRBD are good examples.   </p>
<p>Another good example of efficient Multi-Day visit is when there are multiple groups or multiple applications using MySQL - in such case each of the problem areas/groups can gets its own day or few hours which keeps consultant busy.</p>
<p>To make a Multi-Day visit efficient it is important to plan on what will be done - what people will consultant need to work with and which problems do they have.   Providing proper access and having staging/test systems available are also often required.   </p>
<p><strong>Remote </strong>  work has a benefit of consultant being available in the short time intervals and being able to multi task.  </p>
<p>Working with the customer there are two types of &#8220;waits&#8221; which are often encountered. First - waiting on the customer. It could be fixing access problems, completing application changes, QA,  scheduling downtime to implement changes and millions of other things.      Second - waiting on database (or other) operations to complete - backup, restore,  ALTER TABLE, load testing -  all of these things take time and make consultant to wait for them.   </p>
<p>In case you&#8217;re working remotely consultant typically has other tasks to do while such long processes are  running.  If you&#8217;re spending time onsite you may have other tasks or you may not while if you&#8217;re working remotely there are always things to do.</p>
<p>Another benefit of remote work - it truly allows to engage the team.  If you have consultant onsite getting another one with some specific knowledge is complicated while getting another person to login to the system remotely for a quick look is easy and efficient.  </p>
<p>Time is another interesting factor - onsite visits usually happen during office hours while changes to production are often avoided.  With remote work it is much easier to do work which needs to be done at night hours. </p>
<p>Remote work however also needs to be well organized.  The benefit of onsite work is - it is always planned at very specific time.  Given date and time consultant will be there so both consultant and customer prepare for the visit.  If appointment is just a phone call or online meeting there is larger chance it can be forgotten by ether party.    In many cases the remote work not planned to the specific time at all which can cause it to be delayed because of either party delays. </p>
<p>If you need something to be done fast and you&#8217;re doing it remotely make sure to plan it to exact time and make sure there is someone to assist consultant if he needs any help such as access issues,  some questions about setup or what exactly given queries are doing.  Prompt responses can keep the ball rolling much faster.</p>
<p>Another trick to make remote work successful is to be very clear in your instructions especially if you&#8217;re not going to be available to assist consultant when he is doing the work.  As remote work is often done cross time zones this becomes a very important factor.</p>
<p>In case you have a lot of work done in such &#8220;disconnected&#8221; mode it is a good idea to have daily/weekly/or be-weekly  (depending on project intensity)  calls to get team to discuss the progress and generally get team on the same page.</p>
<p>In general surprisingly a lot of things can be done in completely remote mode - we&#8217;ve done not only basic optimizations but architecture redesigns, large scale deployment, migrations and high available architectures implementation such a way often surprising customers (in a good way) of how little customers the work took. </p>
<p><strong>The Great Mix </strong>  As I mentioned before mixing Onsite and Remote work can be indeed the best mix especially for the complex projects.   Onsite visit is great to setup relationships, get initial understanding of the system and get initial project planning.  After it is done a lot of work can be done remotely quite efficient while there may be the benefit in onsite status-checks and team interactions as well.  </p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2009/07/02/onsite-and-remote-getting-best-of-both-worlds/#comments">No comment</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/07/02/onsite-and-remote-getting-best-of-both-worlds/&amp;title=Onsite and Remote - getting best of both worlds" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/07/02/onsite-and-remote-getting-best-of-both-worlds/&amp;title=Onsite and Remote - getting best of both worlds" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/07/02/onsite-and-remote-getting-best-of-both-worlds/&amp;title=Onsite and Remote - getting best of both worlds" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/07/02/onsite-and-remote-getting-best-of-both-worlds/&amp;T=Onsite and Remote - getting best of both worlds" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/07/02/onsite-and-remote-getting-best-of-both-worlds/&amp;title=Onsite and Remote - getting best of both worlds" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
    <pubDate>Fri, 03 Jul 2009 02:01:20 +0000</pubDate>
    <dc:creator>MySQL Performance Blog</dc:creator>
    <category>percona</category>
  </item>

  <item>
    <title>Scaling w Flash Webinar Recording Available</title>
    <guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=711</guid>
    <link>http://www.mysqlperformanceblog.com/2009/07/02/scaling-w-flash-webinar-recording-available/</link>
    <description>The Scaling with Flash  webinar I&amp;#8217;ve mentioned earlier was a success and we got the recording available.    It contains  Percona presentation,  presentation of Schooner appliances and Q&amp;#038;A session.    Enjoy.
    
    Entry posted by peter |
      No comment
    Add to:  |  |  |  | </description>
    <content:encoded><![CDATA[<p>The Scaling with Flash  <a href="http://www.mysqlperformanceblog.com/2009/06/19/scaling-io-bound-workloads-webinar/">webinar</a> I&#8217;ve mentioned earlier was a success and we got the <a href="https://schooner.webex.com/schooner/ldr.php?AT=pb&amp;SP=MC&amp;rID=30720627&amp;rKey=848208c61469e5f0">recording </a>available.    It contains  Percona presentation,  presentation of Schooner appliances and Q&#038;A session.    Enjoy.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2009/07/02/scaling-w-flash-webinar-recording-available/#comments">No comment</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/07/02/scaling-w-flash-webinar-recording-available/&amp;title=Scaling w Flash Webinar Recording Available" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/07/02/scaling-w-flash-webinar-recording-available/&amp;title=Scaling w Flash Webinar Recording Available" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/07/02/scaling-w-flash-webinar-recording-available/&amp;title=Scaling w Flash Webinar Recording Available" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/07/02/scaling-w-flash-webinar-recording-available/&amp;T=Scaling w Flash Webinar Recording Available" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/07/02/scaling-w-flash-webinar-recording-available/&amp;title=Scaling w Flash Webinar Recording Available" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
    <pubDate>Fri, 03 Jul 2009 00:59:14 +0000</pubDate>
    <dc:creator>MySQL Performance Blog</dc:creator>
    <category>conferences</category>
  </item>

  <item>
    <title>MySQL Proxy 0.7.2 released</title>
    <guid isPermaLink="false">http://blogs.sun.com/kay/entry/mysql_proxy_0_7_2</guid>
    <link>http://blogs.sun.com/kay/entry/mysql_proxy_0_7_2</link>
    <description>The following just went out to our mailing list:


We are happy to announce that MySQL Proxy 0.7.2 is available in a source and binary release for all of our target platforms.


This latest release also brings back Windows support in both the source and binary release.


The list of important changes in this release is:
 * fixed memory leak proxy plugin (#45272)
 * fixed ro-balance.lua (#45408)
 * added CMake build files
 * fixed portability issues for Win32
 * added mysql-proxy-svc on Win32
 * updated INSTALL file to cover all the build steps on win32


Please report any problems on bugs.mysql.com, our Launchpad discussion mailing list or on IRC: #mysql-proxy on irc.freenode.net.


The focus of development is now on MySQL Proxy 0.8.


MySQL Proxy 0.7.2 is currently the recommended version to use unless you develop MySQL Proxy itself.


The packages are available on the MySQL Downloads page.</description>
    <content:encoded><![CDATA[<p>The following just went out to our mailing list:</p>


<p>We are happy to announce that MySQL Proxy 0.7.2 is available in a source and binary release for all of our target platforms.</p>


<p>This latest release also brings back Windows support in both the source and binary release.</p>


<p>The list of important changes in this release is:<br/>
 * fixed memory leak proxy plugin (<a href="http://bugs.mysql.com/45272">#45272</a>)<br/>
 * fixed ro-balance.lua (<a href="http://bugs.mysql.com/45408">#45408</a>)<br/>
 * added CMake build files<br/>
 * fixed portability issues for Win32<br/>
 * added mysql-proxy-svc on Win32<br/>
 * updated INSTALL file to cover all the build steps on win32</p>


<p>Please report any problems on <a href="http://bugs.mysql.com">bugs.mysql.com</a>, our <a href="https://launchpad.net/~mysql-proxy-discuss">Launchpad discussion mailing list</a> or on IRC: #mysql-proxy on irc.freenode.net.</p>


<p>The focus of development is now on MySQL Proxy 0.8.</p>


<p>MySQL Proxy 0.7.2 is currently the recommended version to use unless you develop MySQL Proxy itself.</p>


<p>The packages are available on the <a href="http://dev.mysql.com/downloads/mysql-proxy/index.html">MySQL Downloads page</a>.</p>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 16:50:17 +0000</pubDate>
    <dc:creator>Kay R&amp;ouml;pke</dc:creator>
    <category>MySQL</category>
    <category>mysql</category>
    <category>proxy</category>
    <category>release</category>
  </item>

  <item>
    <title>Is ScaleDB Using MapReduce? Competing with Hadoop?</title>
    <guid isPermaLink="false">http://scaledb.com/component/option,com_wordpress/Itemid,243/p,103/</guid>
    <link>http://scaledb.com/component/option,com_wordpress/Itemid,243/p,103/</link>
    <description>I&amp;#8217;ve had a few VCs ask how we compare to Hadoop and companies using MapReduce. With Google blessing MapReduce, it seems to be the cool new thing. I figure I&amp;#8217;m going to have to explain this to VCs, so I might as well blog about it.
MapReduce is a process of dividing a problem into small pieces and distributing (mapping) those pieces to a large number of computers. Then it collects the processed data and merges (reduces) it into a result set. Hadoop provides the plumbing, so users focus on writing the query and Hadoop handles the dirty work of mapping and reducing. Such a query, using a procedural language like Java, is more complex than a comparable SQL query, but more on that below.
So what is MapReduce good for? It really shines when you want to summarize, analyze or transform a very large data set. This is why it is well suited to web data. Map reduce doesn&amp;#8217;t utilize an index, so the tradeoff you need to consider is whether parallelizing the task provides greater efficiency than leveraging an index. If, for example, you want to find all customers who have placed more than one order in the past year, MapReduce can quickly scan the entire data set and discover how many have placed two or more orders in the past year. In this scenario, exploiting large numbers of computers in parallel is very fast. On the other hand, if you want to find an individual with a specific address, using the index to find that person is more efficient than processing the entire data set.
There is some overlap between the database and MapReduce worlds. MapReduce can help, as in the example above, to extract insights from large quantities of data that is not indexed. It is also helpful in feeding data into your database using processes known as Extract Transform and Load (ETL) and Extract Load and Transform (ELT), depending upon whether the transform step is done before or after loading the data into the database.
MapReduce has been addressed using procedural languages like Java. This is fine for batch processing of static data (e.g. historical sales data from last year). Yahoo&amp;#8217;s Pig and Google&amp;#8217;s Sawzall are attempting to expose the power of MapReduce through declarative languages like SQL, which would simplify the ad hoc processing of static data. Generally speaking, the processing of static data is the realm of Business Intelligence (BI) and Data Warehouses (DW).
The other realm of the database world is dynamic data. Dynamic data means data that is being modified on the fly, generally by multiple writers, while multiple readers are also trying to access the data. In this realm, you want to find a specific data element, lock only the smallest piece of data possible for an update, coordinate concurrent requests to change that data, all while ensuring that the changes are safe-using transactions-and the data remains consistent to readers. These are things that depend heavily on indexes and coordination or locking. MapReduce is not designed to handle these types of demands. Ad hoc processing of dynamic data, the realm of Online Transaction Processing (OLTP) databases is orthogonal to MapReduce. This also happens to be the realm of ScaleDB.
So, in short MapReduce can deliver performance gains in the processing of static data, namely in the BI and DW markets. Some projects to graft on declarative languages may further simplify this process. However, MapReduce does not provide value in the area of managing dynamic data such as the OLTP world.
So the answer is: MapReduce is cool and exciting, but there is no correlation between MapReduce and ScaleDB&amp;#8217;s target market. We don&amp;#8217;t use it, nor do we compete with it.</description>
    <content:encoded><![CDATA[<p>I&#8217;ve had a few VCs ask how we compare to Hadoop and companies using MapReduce. With Google blessing MapReduce, it seems to be the cool new thing. I figure I&#8217;m going to have to explain this to VCs, so I might as well blog about it.</p>
<p>MapReduce is a process of dividing a problem into small pieces and distributing (mapping) those pieces to a large number of computers. Then it collects the processed data and merges (reduces) it into a result set. Hadoop provides the plumbing, so users focus on writing the query and Hadoop handles the dirty work of mapping and reducing. Such a query, using a procedural language like Java, is more complex than a comparable SQL query, but more on that below.</p>
<p>So what is MapReduce good for? It really shines when you want to summarize, analyze or transform a very large data set. This is why it is well suited to web data. Map reduce doesn&#8217;t utilize an index, so the tradeoff you need to consider is whether parallelizing the task provides greater efficiency than leveraging an index. If, for example, you want to find all customers who have placed more than one order in the past year, MapReduce can quickly scan the entire data set and discover how many have placed two or more orders in the past year. In this scenario, exploiting large numbers of computers in parallel is very fast. On the other hand, if you want to find an individual with a specific address, using the index to find that person is more efficient than processing the entire data set.</p>
<p>There is some overlap between the database and MapReduce worlds. MapReduce can help, as in the example above, to extract insights from large quantities of data that is not indexed. It is also helpful in feeding data into your database using processes known as Extract Transform and Load (ETL) and Extract Load and Transform (ELT), depending upon whether the transform step is done before or after loading the data into the database.</p>
<p>MapReduce has been addressed using procedural languages like Java. This is fine for batch processing of static data (e.g. historical sales data from last year). <a href="http://research.yahoo.com/project/90" target="_blank">Yahoo&#8217;s Pig</a> and <a href="http://labs.google.com/papers/sawzall.html" target="_blank">Google&#8217;s Sawzall</a> are attempting to expose the power of MapReduce through declarative languages like SQL, which would simplify the ad hoc processing of static data. Generally speaking, the processing of static data is the realm of Business Intelligence (BI) and Data Warehouses (DW).</p>
<p>The other realm of the database world is dynamic data. Dynamic data means data that is being modified on the fly, generally by multiple writers, while multiple readers are also trying to access the data. In this realm, you want to find a specific data element, lock only the smallest piece of data possible for an update, coordinate concurrent requests to change that data, all while ensuring that the changes are safe-using transactions-and the data remains consistent to readers. These are things that depend heavily on indexes and coordination or locking. MapReduce is not designed to handle these types of demands. Ad hoc processing of dynamic data, the realm of Online Transaction Processing (OLTP) databases is orthogonal to MapReduce. This also happens to be the realm of ScaleDB.</p>
<p>So, in short MapReduce can deliver performance gains in the processing of static data, namely in the BI and DW markets. Some projects to graft on declarative languages may further simplify this process. However, MapReduce does not provide value in the area of managing dynamic data such as the OLTP world.</p>
<p>So the answer is: MapReduce is cool and exciting, but there is no correlation between MapReduce and ScaleDB&#8217;s target market. We don&#8217;t use it, nor do we compete with it.</p>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 16:18:54 +0000</pubDate>
    <dc:creator>Mike Hogan</dc:creator>
    <category>Uncategorized</category>
    <category>hadoop</category>
    <category>mapreduce</category>
    <category>mysql</category>
    <category>scaledb</category>
    <category>vc</category>
  </item>

  <item>
    <title>Dogfooding a pastebin</title>
    <guid isPermaLink="false">http://www.flamingspork.com/blog/?p=1667</guid>
    <link>http://www.flamingspork.com/blog/2009/07/03/dogfooding-a-pastebin/</link>
    <description>http://pastebin.flamingspork.com/
A pastebin running Drizzle and  the Drizzle PHP Extension (which is on top of libdrizzle).</description>
    <content:encoded><![CDATA[<p><a href="http://pastebin.flamingspork.com/">http://pastebin.flamingspork.com/</a></p>
<p>A pastebin running Drizzle and  the Drizzle PHP Extension (which is on top of libdrizzle).</p>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 15:52:58 +0000</pubDate>
    <dc:creator>Stewart Smith</dc:creator>
    <category>drizzle</category>
    <category>drizzle-php-ext</category>
    <category>libdrizzle</category>
    <category>pastebin</category>
  </item>

  <item>
    <title>Save time and energy: How to … (… continued)</title>
    <guid isPermaLink="false">http://mysqlpreacher.com/wordpress/?p=203</guid>
    <link>http://mysqlpreacher.com/wordpress/2009/07/save-time-and-energy-how-to-continued/</link>
    <description>Earlier this year I had published a small blog about being efficient when using mysql prompt. This is a small continuation of it highlighting a couple of other cool features which I really find very useful when working command line (i.e. always!).
The first I&amp;#8217;m gonna list here is setting the prompt itself by typing &amp;#8211; \R mysql \D &gt; thus enabling date and time display at each comand which is great for auditing and record keeping. There is a whole bunch of prompt values which you can find here:

Option 	Description
\c 	A counter that increments for each statement you issue
\D 	The full current date
\d 	The default database
\h 	The server host
\l 	The current delimiter (new in 5.0.25)
\m 	Minutes of the current time
\n 	A newline character
\O 	The current month in three-letter format (Jan, Feb, …)
\o 	The current month in numeric format
\P 	am/pm
\p 	The current TCP/IP port or socket file
\R 	The current time, in 24-hour military time (0–23)
\r 	The current time, standard 12-hour time (1–12)
\S 	Semicolon
\s 	Seconds of the current time
\t 	A tab character
\U 	Your full user_name@host_name account name
\u 	Your user name
\v 	The server version
\w 	The current day of the week in three-letter format (Mon, Tue, …)
\Y 	The current year, four digits
\y 	The current year, two digits
\_ 	A space
\  	A space (a space follows the backslash)
\' 	Single quote
\&quot; 	Double quote
\\ 	A literal “\” backslash character
\x 	x, for any “x” not listed above

The second thing is the \e or edit which lets you edit a long query you might have been writing, in any editor you have set on your machine, most often vi, a must know editor for all of you out there.
Enjoy
Darren</description>
    <content:encoded><![CDATA[<p>Earlier this year I had published a small blog about being efficient when using mysql prompt. This is a small continuation of it highlighting a couple of other cool features which I really find very useful when working command line (i.e. always!).</p>
<p>The first I&#8217;m gonna list here is setting the prompt itself by typing &#8211; <code>\R mysql \D > </code>thus enabling date and time display at each comand which is great for auditing and record keeping. There is a whole bunch of prompt values which you can find <a href="http://dev.mysql.com/doc/refman/5.0/en/mysql-commands.html">here</a>:</p>
<blockquote><p>
<code>Option 	Description<br />
\c 	A counter that increments for each statement you issue<br />
\D 	The full current date<br />
\d 	The default database<br />
\h 	The server host<br />
\l 	The current delimiter (new in 5.0.25)<br />
\m 	Minutes of the current time<br />
\n 	A newline character<br />
\O 	The current month in three-letter format (Jan, Feb, …)<br />
\o 	The current month in numeric format<br />
\P 	am/pm<br />
\p 	The current TCP/IP port or socket file<br />
\R 	The current time, in 24-hour military time (0–23)<br />
\r 	The current time, standard 12-hour time (1–12)<br />
\S 	Semicolon<br />
\s 	Seconds of the current time<br />
\t 	A tab character<br />
\U 	Your full user_name@host_name account name<br />
\u 	Your user name<br />
\v 	The server version<br />
\w 	The current day of the week in three-letter format (Mon, Tue, …)<br />
\Y 	The current year, four digits<br />
\y 	The current year, two digits<br />
\_ 	A space<br />
\  	A space (a space follows the backslash)<br />
\' 	Single quote<br />
\" 	Double quote<br />
\\ 	A literal “\” backslash character<br />
\x 	x, for any “x” not listed above</code></p></blockquote>
<p>
The second thing is the \e or edit which lets you edit a long query you might have been writing, in any editor you have set on your machine, most often <em>vi</em>, a must know editor for all of you out there.</p>
<p>Enjoy<br />
Darren</p>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 14:35:04 +0000</pubDate>
    <dc:creator>Darren Cassar</dc:creator>
    <category>Beginner</category>
    <category>Databases</category>
    <category>MySQL</category>
  </item>

  <item>
    <title>libdrizzle and PHP Extension Released</title>
    <guid isPermaLink="false">http://www.oddments.org/?p=72</guid>
    <link>http://www.oddments.org/?p=72</link>
    <description>Version 0.4 of libdrizzle has been released. This was mostly a maintenance release with build system changes and small bug fixes. This is the client and protocol library for Drizzle and MySQL that provides both client and server interfaces.
Version 0.4.1 of the Drizzle PHP Extension has also been released. James Luedke has moved development and releases of the extension into PECL, and has also fixed a number of bugs, extended the interface, and worked with the PHP/PECL developers to get the extension up to the proper PHP coding standards. Thanks James!</description>
    <content:encoded><![CDATA[<p>Version 0.4 of <a href="https://launchpad.net/libdrizzle">libdrizzle</a> has been released. This was mostly a maintenance release with build system changes and small bug fixes. This is the client and protocol library for Drizzle and MySQL that provides both client and server interfaces.</p>
<p>Version 0.4.1 of the <a href="http://pecl.php.net/package/drizzle/">Drizzle PHP Extension</a> has also been released. <a href="http://jluedke.com/">James Luedke</a> has moved development and releases of the extension into <a href="http://pecl.php.net/">PECL</a>, and has also fixed a number of bugs, extended the interface, and worked with the PHP/PECL developers to get the extension up to the proper PHP coding standards. Thanks James!</p>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 07:14:24 +0000</pubDate>
    <dc:creator>Eric Day</dc:creator>
    <category>Drizzle</category>
    <category>Main</category>
    <category>MySQL</category>
  </item>

  <item>
    <title>Newly born...</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-2814663575336557031.post-3998725824751544457</guid>
    <link>http://igors-notes.blogspot.com/2009/07/newly-born.html</link>
    <description>Yesterday I still worked for Sun Microsystems as a Principal Engineer &amp; MySQL Sr. Architect. Today was my first day of work at Monty Program, Inc, a subsidiary  of a tiny company established by Monty Widenius in February. Yet I didn't even make the top ten. If people want not to miss the train they have to hurry up.Am I happy? Oh, yeah...No more waking up with the question constantly drilling my mind: “What am I doing here?”  What are all of us, MySQL  Server developers, doing without Monty? Waiting for the time when all our options are vested? I can't . That's too long for me. I'm already too old  to wait any more.Besides, we've already lost at least 3 years. We have to do what we planned to do in 2005. We have to raise the Server to the level where any RDBMS that claims to be called mature should be.So who is newly born? Me? In a way, yes. This is my second reincarnation for the history of MySQL, after the first one that happened in December 2002 .Also newly born is this blog where I'm planning to share with you, from time to time, my observations on  the Server development at Monty Program and on interesting patches in the  new server code that other people contribute. However, I don't want to limit myself only to this topic. What else am I going to share with you? You'll see soon enough...</description>
    <content:encoded><![CDATA[Yesterday I still worked for Sun Microsystems as a Principal Engineer & MySQL Sr. Architect. Today was my first day of work at Monty Program, Inc, a subsidiary  of a tiny company established by Monty Widenius in February. Yet I didn't even make the top ten. If people want not to miss the train they have to hurry up.<br /><br />Am I happy? Oh, yeah...<br />No more waking up with the question constantly drilling my mind: “What am I doing here?”  What are all of us, MySQL  Server developers, doing without Monty? Waiting for the time when all our options are vested? I can't . That's too long for me. I'm already too old  to wait any more.<br />Besides, we've already lost at least 3 years. We have to do what we planned to do in 2005. We have to raise the Server to the level where any RDBMS that claims to be called mature should be.<br /><br />So who is newly born? Me? In a way, yes. This is my second reincarnation for the history of MySQL, after the first one that happened in December 2002 .<br /><br />Also newly born is this blog where I'm planning to share with you, from time to time, my observations on  the Server development at Monty Program and on interesting patches in the  new server code that other people contribute. However, I don't want to limit myself only to this topic. What else am I going to share with you? You'll see soon enough...<div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/2814663575336557031-3998725824751544457?l=igors-notes.blogspot.com" /></div>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 07:09:00 +0000</pubDate>
    <dc:creator>Igor Babaev</dc:creator>
  </item>

  <item>
    <title>Gearman Releases</title>
    <guid isPermaLink="false">http://www.oddments.org/?p=71</guid>
    <link>http://www.oddments.org/?p=71</link>
    <description>Version 0.8 of the Gearman C Server and Library has been released. This includes basic HTTP protocol support, build system improvements, and bug fixes. 
Version 0.4.0 of the Gearman PHP Extension has also been released.
If you want to learn more about Gearman, be sure to check out the upcoming Boston MySQL Meetup, MySQL Webinar, or the one of the events at OSCON (tutorial, session, and BoF).</description>
    <content:encoded><![CDATA[<p>Version 0.8 of the <a href="https://launchpad.net/gearmand">Gearman C Server and Library</a> has been released. This includes basic HTTP protocol support, build system improvements, and bug fixes. </p>
<p>Version 0.4.0 of the <a href="http://pecl.php.net/packages/gearman">Gearman PHP Extension</a> has also been released.</p>
<p>If you want to learn more about Gearman, be sure to check out the upcoming <a href="http://www.meetup.com/mysqlbos/calendar/10607736/">Boston MySQL Meetup</a>, <a href="http://mysql.com/news-and-events/web-seminars/display-387.html">MySQL Webinar</a>, or the one of the events at <a href="http://en.oreilly.com/oscon2009">OSCON</a> (<a href="http://en.oreilly.com/oscon2009/public/schedule/detail/8206">tutorial</a>, <a href="http://en.oreilly.com/oscon2009/public/schedule/detail/8198">session</a>, and <a href="http://en.oreilly.com/oscon2009/public/schedule/detail/9775">BoF</a>).</p>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 06:58:34 +0000</pubDate>
    <dc:creator>Eric Day</dc:creator>
    <category>Drizzle</category>
    <category>Gearman</category>
    <category>Main</category>
    <category>MySQL</category>
  </item>

  <item>
    <title>Gathering queries from a server with Maatkit and tcpdump</title>
    <guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=710</guid>
    <link>http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/</link>
    <description>For the last couple of months, we've been quietly developing a MySQL protocol parser for Maatkit.  It isn't an implementation of the protocol: it's an observer of the protocol.  This lets us gather queries from servers that don't have a slow query log enabled, at very high time resolution.
With this new functionality, it becomes possible for mk-query-digest to stand on the sidelines and watch queries fly by over TCP.  It is only an observer on the sidelines: it is NOT a man in the middle like mysql-proxy, so it has basically zero impact on the running server (tcpdump is very efficient) and zero impact on the query latency.  There are some unique challenges to watching an entire server's traffic, but we've found ways to solve those.  Some of them are harder than others, such as making sense of a conversation when you start listening in the middle.  In general, it's working very well.  We can gather just about every bit of information about queries that mysql-proxy can, making this a viable way to monitor servers without the disadvantages of a proxy.  In theory, we can gather ALL the same information, but in practice we are going for the 95% case.
As always with Maatkit, this has minimal dependencies.  It doesn't require any Net::Pcap or other modules from CPAN.  It's written in pure Perl, and it parses the output of tcpdump, rather than watching the network traffic directly.  This might sound useless, but it's not.  It means you can go tcpdump some traffic on a machine without Perl installed, and copy it to another machine for analysis, or send it via email to your friendly consultant, or do any of a number of other things.  Decoupling things is very helpful sometimes.
Let's see how to gather queries and do something useful with them.  I'll just watch the queries on a sandbox server on my laptop, and print out the profile synopsis so you can see how it works.
PLAIN TEXT
CODE:




sudo tcpdump -i lo port 3306 -s 65535 -x -n -q -tttt&amp;#62; tcpdump.out 






I run a few queries, quit, and cancel tcpdump.  Now I've got a file and I'm ready to analyze it.  Let's see:
PLAIN TEXT
CODE:




mk-query-digest --type=tcpdump --report-format=profile tcpdump.out


# Rank Query ID&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Response time&amp;nbsp; &amp;nbsp; Calls&amp;nbsp; &amp;nbsp;R/Call&amp;nbsp; &amp;nbsp; &amp;nbsp;Item


# ==== ================== ================ ======= ========== ====


#&amp;nbsp; &amp;nbsp; 1 0x088084BF139954D8&amp;nbsp; &amp;nbsp; &amp;nbsp;0.1009 90.2%&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;1&amp;nbsp; &amp;nbsp;0.100881 SELECT dual


#&amp;nbsp; &amp;nbsp; 2 0x261703E684370D2C&amp;nbsp; &amp;nbsp; &amp;nbsp;0.0110&amp;nbsp; 9.8%&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;1&amp;nbsp; &amp;nbsp;0.011017 






I'm kind of showing off the summary profile here to illustrate that you can get really compact results to see what's going on inside your server.  What do you suppose that one query was that took a tenth of a second?  We can find out.
PLAIN TEXT
CODE:




mk-query-digest --type=tcpdump --limit 1 tcpdump.out


# 460ms user time, 30ms system time, 8.88M rss, 11.79M vsz


# Overall: 8 total, 6 unique, 0.15 QPS, 0.00x concurrency ________________


#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; total&amp;nbsp; &amp;nbsp; &amp;nbsp;min&amp;nbsp; &amp;nbsp; &amp;nbsp;max&amp;nbsp; &amp;nbsp; &amp;nbsp;avg&amp;nbsp; &amp;nbsp; &amp;nbsp;95%&amp;nbsp; stddev&amp;nbsp; median


# Exec time&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 114ms&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp;101ms&amp;nbsp; &amp;nbsp; 14ms&amp;nbsp; &amp;nbsp;100ms&amp;nbsp; &amp;nbsp; 33ms&amp;nbsp; &amp;nbsp;737us


# Hosts&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 8


# Time range&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-07-01 23:55:41.334082 to 2009-07-01 23:56:33.929945


# bytes&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 215&amp;nbsp; &amp;nbsp; &amp;nbsp; 14&amp;nbsp; &amp;nbsp; &amp;nbsp; 49&amp;nbsp; &amp;nbsp;26.88&amp;nbsp; &amp;nbsp;46.83&amp;nbsp; &amp;nbsp; 9.76&amp;nbsp; &amp;nbsp;26.08


# Errors&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8


# Rows affe&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0


# Warning c&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0


#&amp;nbsp; &amp;nbsp;0% No_good_index_used


#&amp;nbsp; 12% No_index_used


&amp;nbsp;


# Query 1: 0 QPS, 0x concurrency, ID 0x088084BF139954D8 at byte 7517 _____


# This item is included in the report because it matches --limit.


#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pct&amp;nbsp; &amp;nbsp;total&amp;nbsp; &amp;nbsp; &amp;nbsp;min&amp;nbsp; &amp;nbsp; &amp;nbsp;max&amp;nbsp; &amp;nbsp; &amp;nbsp;avg&amp;nbsp; &amp;nbsp; &amp;nbsp;95%&amp;nbsp; stddev&amp;nbsp; median


# Count&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;12&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;1


# Exec time&amp;nbsp; &amp;nbsp; &amp;nbsp;88&amp;nbsp; &amp;nbsp;101ms&amp;nbsp; &amp;nbsp;101ms&amp;nbsp; &amp;nbsp;101ms&amp;nbsp; &amp;nbsp;101ms&amp;nbsp; &amp;nbsp;101ms&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp;101ms


# Users&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1 msandbox


# Hosts&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1 127.0.0.1


# Databases&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1


# Time range 2009-07-01 23:56:31.022602 to 2009-07-01 23:56:31.022602


# bytes&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;22&amp;nbsp; &amp;nbsp; &amp;nbsp; 49&amp;nbsp; &amp;nbsp; &amp;nbsp; 49&amp;nbsp; &amp;nbsp; &amp;nbsp; 49&amp;nbsp; &amp;nbsp; &amp;nbsp; 49&amp;nbsp; &amp;nbsp; &amp;nbsp; 49&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; 49


# Errors&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;1&amp;nbsp; &amp;nbsp; none


# Rows affe&amp;nbsp; &amp;nbsp; &amp;nbsp; 0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0


# Warning c&amp;nbsp; &amp;nbsp; &amp;nbsp; 0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0


#&amp;nbsp; &amp;nbsp;0% No_good_index_used


#&amp;nbsp; &amp;nbsp;0% No_index_used


# Query_time distribution


#&amp;nbsp; &amp;nbsp;1us


#&amp;nbsp; 10us


# 100us


#&amp;nbsp; &amp;nbsp;1ms


#&amp;nbsp; 10ms


# 100ms&amp;nbsp; ################################################################


#&amp;nbsp; &amp;nbsp; 1s


#&amp;nbsp; 10s+


# Tables


#&amp;nbsp; &amp;nbsp; SHOW TABLE STATUS LIKE 'dual'\G


#&amp;nbsp; &amp;nbsp; SHOW CREATE TABLE `dual`\G


# EXPLAIN


select 1 from &amp;#40; select sleep&amp;#40;.1&amp;#41; from dual &amp;#41; as x\G 






Indeed, it's no surprise the query took a tenth of a second to execute, and now you see where &quot;SELECT dual&quot; comes from.
Notice that it is inspecting the protocol enough to see the flags set in the protocol, indicating the warning count, error count, rows affected, and whether no index or no good index was available.  Look at the top of the report -- what is up with the 12% of queries that say No_index_used?  If we increase --limit a bit, we can see 
PLAIN TEXT
CODE:




#&amp;nbsp; &amp;nbsp;0% No_good_index_used


# 100% No_index_used


# Query_time distribution


... snip ...


show databases\G 






I did not know that SHOW DATABASES sets the &quot;no index used&quot; flag, did you?  Now we both do!
This is just a brief introduction to what the protocol parser can do.  Of course, in real life it's much more useful than just seeing a query or two -- it has all the power of mk-query-digest for filtering, aggregating, printing and so forth.
    
    Entry posted by Baron Schwartz |
      16 comments
    Add to:  |  |  |  | </description>
    <content:encoded><![CDATA[<p>For the last couple of months, we've been quietly developing a MySQL protocol parser for Maatkit.  It isn't an implementation of the protocol: it's an observer of the protocol.  This lets us gather queries from servers that don't have a slow query log enabled, at very high time resolution.</p>
<p>With this new functionality, it becomes possible for mk-query-digest to stand on the sidelines and watch queries fly by over TCP.  It is only an observer on the sidelines: it is NOT a man in the middle like mysql-proxy, so it has basically zero impact on the running server (tcpdump is very efficient) and <a href="http://www.mysqlperformanceblog.com/2009/06/09/mysql-proxy-urgh-performance-and-scalability/">zero impact on the query latency</a>.  There are some unique challenges to watching an entire server's traffic, but we've found ways to solve those.  Some of them are harder than others, such as making sense of a conversation when you start listening in the middle.  In general, it's working very well.  We can gather just about every bit of information about queries that mysql-proxy can, making this a viable way to monitor servers without the disadvantages of a proxy.  In theory, we can gather ALL the same information, but in practice we are going for the 95% case.</p>
<p>As always with Maatkit, this has minimal dependencies.  It doesn't require any Net::Pcap or other modules from CPAN.  It's written in pure Perl, and it parses the output of tcpdump, rather than watching the network traffic directly.  This might sound useless, but it's not.  It means you can go tcpdump some traffic on a machine without Perl installed, and copy it to another machine for analysis, or send it via email to your friendly consultant, or do any of a number of other things.  Decoupling things is very helpful sometimes.</p>
<p>Let's see how to gather queries and do something useful with them.  I'll just watch the queries on a sandbox server on my laptop, and print out the profile synopsis so you can see how it works.</p>
<div><span><a href="http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/">PLAIN TEXT</a></span></div>
<div><span>CODE:</span>
<div>
<div>
<ol>
<li>
<div>sudo tcpdump -i lo port <span>3306</span> -s <span>65535</span> -x -n -q -tttt&#62; tcpdump.<span>out</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>I run a few queries, quit, and cancel tcpdump.  Now I've got a file and I'm ready to analyze it.  Let's see:</p>
<div><span><a href="http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/">PLAIN TEXT</a></span></div>
<div><span>CODE:</span>
<div>
<div>
<ol>
<li>
<div>mk-query-digest --type=tcpdump --report-format=profile tcpdump.<span>out</span></div>
</li>
<li>
<div># Rank Query ID&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Response time&nbsp; &nbsp; Calls&nbsp; &nbsp;R/Call&nbsp; &nbsp; &nbsp;Item</div>
</li>
<li>
<div># ==== ================== ================ ======= ========== ====</div>
</li>
<li>
<div>#&nbsp; &nbsp; <span>1</span> 0x088084BF139954D8&nbsp; &nbsp; &nbsp;<span>0</span>.<span>1009</span> <span>90</span>.<span>2</span>%&nbsp; &nbsp; &nbsp; &nbsp;<span>1</span>&nbsp; &nbsp;<span>0</span>.<span>100881</span> SELECT dual</div>
</li>
<li>
<div>#&nbsp; &nbsp; <span>2</span> 0x261703E684370D2C&nbsp; &nbsp; &nbsp;<span>0</span>.<span>0110</span>&nbsp; <span>9</span>.<span>8</span>%&nbsp; &nbsp; &nbsp; &nbsp;<span>1</span>&nbsp; &nbsp;<span>0</span>.<span>011017</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>I'm kind of showing off the summary profile here to illustrate that you can get really compact results to see what's going on inside your server.  What do you suppose that one query was that took a tenth of a second?  We can find out.</p>
<div><span><a href="http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/">PLAIN TEXT</a></span></div>
<div><span>CODE:</span>
<div>
<div>
<ol>
<li>
<div>mk-query-digest --type=tcpdump --limit <span>1</span> tcpdump.<span>out</span></div>
</li>
<li>
<div># 460ms user time, 30ms system time, <span>8</span>.88M rss, <span>11</span>.79M vsz</div>
</li>
<li>
<div># Overall: <span>8</span> total, <span>6</span> unique, <span>0</span>.<span>15</span> QPS, <span>0</span>.00x concurrency ________________</div>
</li>
<li>
<div>#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; total&nbsp; &nbsp; &nbsp;min&nbsp; &nbsp; &nbsp;max&nbsp; &nbsp; &nbsp;avg&nbsp; &nbsp; &nbsp;<span>95</span>%&nbsp; stddev&nbsp; median</div>
</li>
<li>
<div># Exec time&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 114ms&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp;101ms&nbsp; &nbsp; 14ms&nbsp; &nbsp;100ms&nbsp; &nbsp; 33ms&nbsp; &nbsp;737us</div>
</li>
<li>
<div># Hosts&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span>8</span></div>
</li>
<li>
<div># Time range&nbsp; &nbsp; &nbsp; &nbsp; <span>2009</span>-<span>07</span>-<span>01</span> <span>23</span>:<span>55</span>:<span>41</span>.<span>334082</span> to <span>2009</span>-<span>07</span>-<span>01</span> <span>23</span>:<span>56</span>:<span>33</span>.<span>929945</span></div>
</li>
<li>
<div># bytes&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span>215</span>&nbsp; &nbsp; &nbsp; <span>14</span>&nbsp; &nbsp; &nbsp; <span>49</span>&nbsp; &nbsp;<span>26</span>.<span>88</span>&nbsp; &nbsp;<span>46</span>.<span>83</span>&nbsp; &nbsp; <span>9</span>.<span>76</span>&nbsp; &nbsp;<span>26</span>.<span>08</span></div>
</li>
<li>
<div># Errors&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span>8</span></div>
</li>
<li>
<div># Rows affe&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span></div>
</li>
<li>
<div># Warning c&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span></div>
</li>
<li>
<div>#&nbsp; &nbsp;<span>0</span>% No_good_index_used</div>
</li>
<li>
<div>#&nbsp; <span>12</span>% No_index_used</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div># Query <span>1</span>: <span>0</span> QPS, 0x concurrency, ID 0x088084BF139954D8 at byte <span>7517</span> _____</div>
</li>
<li>
<div># This item is included in the report because it matches --limit.</div>
</li>
<li>
<div>#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pct&nbsp; &nbsp;total&nbsp; &nbsp; &nbsp;min&nbsp; &nbsp; &nbsp;max&nbsp; &nbsp; &nbsp;avg&nbsp; &nbsp; &nbsp;<span>95</span>%&nbsp; stddev&nbsp; median</div>
</li>
<li>
<div># Count&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span>12</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>1</span></div>
</li>
<li>
<div># Exec time&nbsp; &nbsp; &nbsp;<span>88</span>&nbsp; &nbsp;101ms&nbsp; &nbsp;101ms&nbsp; &nbsp;101ms&nbsp; &nbsp;101ms&nbsp; &nbsp;101ms&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp;101ms</div>
</li>
<li>
<div># Users&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span>1</span> msandbox</div>
</li>
<li>
<div># Hosts&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span>1</span> <span>127</span>.<span>0</span>.<span>0</span>.<span>1</span></div>
</li>
<li>
<div># Databases&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span>1</span></div>
</li>
<li>
<div># Time range <span>2009</span>-<span>07</span>-<span>01</span> <span>23</span>:<span>56</span>:<span>31</span>.<span>022602</span> to <span>2009</span>-<span>07</span>-<span>01</span> <span>23</span>:<span>56</span>:<span>31</span>.<span>022602</span></div>
</li>
<li>
<div># bytes&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span>22</span>&nbsp; &nbsp; &nbsp; <span>49</span>&nbsp; &nbsp; &nbsp; <span>49</span>&nbsp; &nbsp; &nbsp; <span>49</span>&nbsp; &nbsp; &nbsp; <span>49</span>&nbsp; &nbsp; &nbsp; <span>49</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; <span>49</span></div>
</li>
<li>
<div># Errors&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span>1</span>&nbsp; &nbsp; none</div>
</li>
<li>
<div># Rows affe&nbsp; &nbsp; &nbsp; <span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span></div>
</li>
<li>
<div># Warning c&nbsp; &nbsp; &nbsp; <span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span>&nbsp; &nbsp; &nbsp; &nbsp;<span>0</span></div>
</li>
<li>
<div>#&nbsp; &nbsp;<span>0</span>% No_good_index_used</div>
</li>
<li>
<div>#&nbsp; &nbsp;<span>0</span>% No_index_used</div>
</li>
<li>
<div># Query_time distribution</div>
</li>
<li>
<div>#&nbsp; &nbsp;1us</div>
</li>
<li>
<div>#&nbsp; 10us</div>
</li>
<li>
<div># 100us</div>
</li>
<li>
<div>#&nbsp; &nbsp;1ms</div>
</li>
<li>
<div>#&nbsp; 10ms</div>
</li>
<li>
<div># 100ms&nbsp; ################################################################</div>
</li>
<li>
<div>#&nbsp; &nbsp; 1s</div>
</li>
<li>
<div>#&nbsp; 10s+</div>
</li>
<li>
<div># Tables</div>
</li>
<li>
<div>#&nbsp; &nbsp; SHOW TABLE STATUS LIKE <span>'dual'</span>\G</div>
</li>
<li>
<div>#&nbsp; &nbsp; SHOW CREATE TABLE `dual`\G</div>
</li>
<li>
<div># EXPLAIN</div>
</li>
<li>
<div>select <span>1</span> from <span>&#40;</span> select sleep<span>&#40;</span>.<span>1</span><span>&#41;</span> from dual <span>&#41;</span> as x\G </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Indeed, it's no surprise the query took a tenth of a second to execute, and now you see where "SELECT dual" comes from.</p>
<p>Notice that it is inspecting the protocol enough to see the flags set in the protocol, indicating the warning count, error count, rows affected, and whether no index or no good index was available.  Look at the top of the report -- what is up with the 12% of queries that say No_index_used?  If we increase --limit a bit, we can see </p>
<div><span><a href="http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/">PLAIN TEXT</a></span></div>
<div><span>CODE:</span>
<div>
<div>
<ol>
<li>
<div>#&nbsp; &nbsp;<span>0</span>% No_good_index_used</div>
</li>
<li>
<div># <span>100</span>% No_index_used</div>
</li>
<li>
<div># Query_time distribution</div>
</li>
<li>
<div>... <span>snip</span> ...</div>
</li>
<li>
<div><span>show</span> databases\G </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>I did not know that SHOW DATABASES sets the "no index used" flag, did you?  Now we both do!</p>
<p>This is just a brief introduction to what the protocol parser can do.  Of course, in real life it's much more useful than just seeing a query or two -- it has all the power of mk-query-digest for filtering, aggregating, printing and so forth.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/#comments">16 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/&amp;title=Gathering queries from a server with Maatkit and tcpdump" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/&amp;title=Gathering queries from a server with Maatkit and tcpdump" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/&amp;title=Gathering queries from a server with Maatkit and tcpdump" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/&amp;T=Gathering queries from a server with Maatkit and tcpdump" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/07/01/gathering-queries-from-a-server-with-maatkit-and-tcpdump/&amp;title=Gathering queries from a server with Maatkit and tcpdump" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 04:10:24 +0000</pubDate>
    <dc:creator>MySQL Performance Blog</dc:creator>
    <category>tools</category>
  </item>

  <item>
    <title>TweetMeme Migrates to Sun's MySQL Enterprise Database Subscription Service</title>
    <guid isPermaLink="false">http://uk.sun.com/sunnews/press/2009/2009-06-30.jsp</guid>
    <link>http://uk.sun.com/sunnews/press/2009/2009-06-30.jsp</link>
    <description>Sun Microsystems, Inc. today announced that TweetMeme, the innovative online application that tracks the popularity of links sent via Twitter, has subscribed to Sun's MySQL Enterprise database offering in order to keep up with the microblogging service's explosive growth.

Created in 2008 by pioneering Web 2.0 startup Fav.or.it, TweetMeme gives the rapidly expanding Twitter community a means of easily seeing and sorting the most popular links on Twitter. TweetMeme also provides a realtime search facility of fully expanded, qualified and indexed links so that users can get answers to queries about very recent events or news.</description>
    <content:encoded><![CDATA[Sun Microsystems, Inc. today announced that TweetMeme, the innovative online application that tracks the popularity of links sent via Twitter, has subscribed to Sun's MySQL Enterprise database offering in order to keep up with the microblogging service's explosive growth.

<p>Created in 2008 by pioneering Web 2.0 startup Fav.or.it, TweetMeme gives the rapidly expanding Twitter community a means of easily seeing and sorting the most popular links on Twitter. TweetMeme also provides a realtime search facility of fully expanded, qualified and indexed links so that users can get answers to queries about very recent events or news.</p>]]></content:encoded>
    <pubDate>Thu, 02 Jul 2009 00:59:59 +0000</pubDate>
    <dc:creator>MySQL</dc:creator>
  </item>

  <item>
    <title>MySQL Cluster Multi-Range Read using NDB API</title>
    <guid isPermaLink="false">http://www.clusterdb.com/?p=227</guid>
    <link>http://www.clusterdb.com/mysql-cluster/mysql-cluster-multi-range-read-using-ndb-api/</link>
    <description>As described in &amp;#8220;Batching - improving MySQL Cluster performance when using the NDB API&amp;#8220;, reducing the number of times the application node has to access the data nodes can greatly improve performance and reduce latency. That article focussed on setting up multiple operatations (as part of a single transaction) and then executing them as a single batch sent by the NDB API library to the data nodes.
The purpose of this entry is to show how a single NDB API operation can access multiple rows from a table with a single index lookup. It goes on to explain the signifficance of this both now and in the future (much faster joins using SQL for MySQL Cluster tables).
There are several operation types to cover table scans and index lookups (refer to the &amp;#8220;MySQL Cluster API Developer Guide&amp;#8221; for detals). For this example, I use an NdbIndexScanOperation.
The code sample assumes that the following table structure and data has been set up for table &amp;#8220;COUNTRY&amp;#8221; in database &amp;#8220;TEST_DB_1&amp;#8243; using the NDB storage engine (Note that the full example application sets this up automatically):
+--------------+------------------+------+-----+---------+-------+
| Field        | Type             | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| SUB_ID       | int(10) unsigned | NO   | PRI | NULL    |       |
| COUNTRY_CODE | int(10) unsigned | NO   |     | NULL    |       |
+--------------+------------------+------+-----+---------+-------+

+--------+--------------+
| SUB_ID | COUNTRY_CODE |
+--------+--------------+
|     13 |            1 |
|      2 |            1 |
|      4 |           61 |
|      7 |           46 |
|      9 |           44 |
|     10 |           33 |
|     12 |           44 |
|      5 |           33 |
|     14 |           61 |
|      1 |           44 |
|      8 |            1 |
+--------+--------------+
The following code causes the NDB API library to send a single request from the application to the data nodes to read the rows where the primary key &amp;#8220;SUB_ID&amp;#8221; falls into the ranges (2&amp;#60;= SUB_ID &amp;#60;4); (5 &amp;#60; SUB_ID &amp;#60;=9) or (SUB_ID == 13). Note that this is just a fragment of the code and the error checking has been removed for clarity (refer to  full example application to see the rest of the code, including the error handling).
NdbIndexScanOperation *psop;

/* RecAttrs for NdbRecAttr Api */
NdbRecAttr *recAttrAttr1;
NdbRecAttr *recAttrAttr2;

psop=myTransaction-&amp;#62;getNdbIndexScanOperation(myPIndex);

Uint32 scanFlags=
  NdbScanOperation::SF_OrderBy |
  NdbScanOperation::SF_MultiRange |
  NdbScanOperation::SF_ReadRangeNo;

psop-&amp;#62;readTuples(NdbOperation::LM_Read,
                 scanFlags,
                 (Uint32) 0,          // batch
                 (Uint32) 0)          // parallel

/* Add a bound
* Tuples where SUB_ID &amp;#62;=2 and &amp;#60; 4
*/
Uint32 low=2;
Uint32 high=4;
Uint32 match=13;

psop-&amp;#62;setBound(&quot;SUB_ID&quot;, NdbIndexScanOperation::BoundLE, (char*)&amp;#38;low);
psop-&amp;#62;setBound(&quot;SUB_ID&quot;, NdbIndexScanOperation::BoundGT, (char*)&amp;#38;high);
psop-&amp;#62;end_of_bound(0);

/* Second bound
* Tuples where SUB_ID &amp;#62; 5 and &amp;#60;=9
*/
low=5;
high=9;
psop-&amp;#62;setBound(&quot;SUB_ID&quot;, NdbIndexScanOperation::BoundLT, (char*)&amp;#38;low);
psop-&amp;#62;setBound(&quot;SUB_ID&quot;, NdbIndexScanOperation::BoundGE, (char*)&amp;#38;high);
psop-&amp;#62;end_of_bound(1);

/* Third bound
* Tuples where SUB_ID == 13
*/
psop-&amp;#62;setBound(&quot;SUB_ID&quot;, NdbIndexScanOperation::BoundEQ, (char*)&amp;#38;match);
psop-&amp;#62;end_of_bound(2);

/* Read all columns */
recAttrAttr1=psop-&amp;#62;getValue(&quot;SUB_ID&quot;);
recAttrAttr2=psop-&amp;#62;getValue(&quot;COUNTRY_CODE&quot;);

myTransaction-&amp;#62;execute( NdbTransaction::Commit);

while (psop-&amp;#62;nextResult(true) == 0)
{
  printf(&quot; %8d    %8d   Range no : %2d\n&quot;,
  recAttrAttr1-&amp;#62;u_32_value(),
  recAttrAttr2-&amp;#62;u_32_value(),
  psop-&amp;#62;get_range_no());
}
psop-&amp;#62;close();
When run, this code produces the following output:
SUB_ID    COUNTRY_CODE
2           1   Range no :  0
7          46   Range no :  1
8           1   Range no :  1
9          44   Range no :  1
13          1   Range no :  2
Why is this signifficant?
This can be very useful for applications using the NDB API; imagine an application that wanted to find the birthdays for all of my friends. Assume that I have 2 tables of interest:
mysql&amp;#62; describe friends; describe birthday;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| name   | varchar(30) | NO   | PRI | NULL    |       |
| friend | varchar(30) | NO   | PRI |         |       |
+--------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(30) | NO   | PRI | NULL    |       |
| day   | int(11)     | YES  |     | NULL    |       |
| month | int(11)     | YES  |     | NULL    |       |
| year  | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
Using the NDB API, I can create 1 NdbIndexScanOperation operation to read all tuples from &amp;#8220;friends&amp;#8221; where the &amp;#8220;name&amp;#8221; field matches &amp;#8220;Andrew&amp;#8221; and then use the results to perform a second NdbIndexScanOperation to read the rows that match each of my friends&amp;#8217; names in the &amp;#8220;birthday&amp;#8221; table. In other words, performing a join using only 2 trips from the application to the data nodes.

Of course, it&amp;#8217;s simple to get the same results using SQL&amp;#8230;SELECT birthday.name, birthday.day, birthday.month FROM friends, birthday WHERE friend.name='Andrew' AND friends.friend=birthday.name;However, if the tables are very large and I have a lot of friends then performing this join using SQL can be expensive as it requires a separate trip to the data nodes to fetch each birthday. In the future, Batched Key Access (BKA) will optimise these joins by performing one of these NDB API Multi-Range Reads (MRR) to fetch all of the birthdays in one go!  Until then, using the NDB API directly can deliver signifficantly faster results.</description>
    <content:encoded><![CDATA[<p>As described in &#8220;<a href="http://www.clusterdb.com/mysql-cluster/batching-improving-mysql-cluster-performance-when-using-the-ndb-api/" target="_blank">Batching - improving MySQL Cluster performance when using the NDB API</a>&#8220;, reducing the number of times the application node has to access the data nodes can greatly improve performance and reduce latency. That article focussed on setting up multiple operatations (as part of a single transaction) and then executing them as a single batch sent by the NDB API library to the data nodes.</p>
<p>The purpose of this entry is to show how a single NDB API operation can access multiple rows from a table with a single index lookup. It goes on to explain the signifficance of this both now and in the future (much faster joins using SQL for MySQL Cluster tables).</p>
<p>There are several operation types to cover table scans and index lookups (refer to the &#8220;<a href="http://dev.mysql.com/doc/ndbapi/en/index.html" target="_blank">MySQL Cluster API Developer Guide</a>&#8221; for detals). For this example, I use an NdbIndexScanOperation.</p>
<p>The code sample assumes that the following table structure and data has been set up for table &#8220;COUNTRY&#8221; in database &#8220;TEST_DB_1&#8243; using the NDB storage engine (Note that the <a href="http://www.clusterdb.com/wp-content/uploads/2009/07/mrr_example.cpp" target="_blank">full example application </a>sets this up automatically):</p>
<pre>+--------------+------------------+------+-----+---------+-------+
| Field        | Type             | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| SUB_ID       | int(10) unsigned | NO   | PRI | NULL    |       |
| COUNTRY_CODE | int(10) unsigned | NO   |     | NULL    |       |
+--------------+------------------+------+-----+---------+-------+

+--------+--------------+
| SUB_ID | COUNTRY_CODE |
+--------+--------------+
|     13 |            1 |
|      2 |            1 |
|      4 |           61 |
|      7 |           46 |
|      9 |           44 |
|     10 |           33 |
|     12 |           44 |
|      5 |           33 |
|     14 |           61 |
|      1 |           44 |
|      8 |            1 |
+--------+--------------+</pre>
<p>The following code causes the NDB API library to send a single request from the application to the data nodes to read the rows where the primary key &#8220;SUB_ID&#8221; falls into the ranges (2&#60;= SUB_ID &#60;4); (5 &#60; SUB_ID &#60;=9) or (SUB_ID == 13). Note that this is just a fragment of the code and the error checking has been removed for clarity (refer to  <a href="http://www.clusterdb.com/wp-content/uploads/2009/07/mrr_example.cpp" target="_blank">full example application </a>to see the rest of the code, including the error handling).</p>
<pre>NdbIndexScanOperation *psop;

/* RecAttrs for NdbRecAttr Api */
NdbRecAttr *recAttrAttr1;
NdbRecAttr *recAttrAttr2;

psop=myTransaction-&#62;getNdbIndexScanOperation(myPIndex);

Uint32 scanFlags=
  NdbScanOperation::SF_OrderBy |
  NdbScanOperation::SF_MultiRange |
  NdbScanOperation::SF_ReadRangeNo;

psop-&#62;readTuples(NdbOperation::LM_Read,
                 scanFlags,
                 (Uint32) 0,          // batch
                 (Uint32) 0)          // parallel

/* Add a bound
* Tuples where SUB_ID &#62;=2 and &#60; 4
*/
Uint32 low=2;
Uint32 high=4;
Uint32 match=13;

psop-&#62;setBound("SUB_ID", NdbIndexScanOperation::BoundLE, (char*)&#38;low);
psop-&#62;setBound("SUB_ID", NdbIndexScanOperation::BoundGT, (char*)&#38;high);
psop-&#62;end_of_bound(0);

/* Second bound
* Tuples where SUB_ID &#62; 5 and &#60;=9
*/
low=5;
high=9;
psop-&#62;setBound("SUB_ID", NdbIndexScanOperation::BoundLT, (char*)&#38;low);
psop-&#62;setBound("SUB_ID", NdbIndexScanOperation::BoundGE, (char*)&#38;high);
psop-&#62;end_of_bound(1);

/* Third bound
* Tuples where SUB_ID == 13
*/
psop-&#62;setBound("SUB_ID", NdbIndexScanOperation::BoundEQ, (char*)&#38;match);
psop-&#62;end_of_bound(2);

/* Read all columns */
recAttrAttr1=psop-&#62;getValue("SUB_ID");
recAttrAttr2=psop-&#62;getValue("COUNTRY_CODE");

myTransaction-&#62;execute( NdbTransaction::Commit);

while (psop-&#62;nextResult(true) == 0)
{
  printf(" %8d    %8d   Range no : %2d\n",
  recAttrAttr1-&#62;u_32_value(),
  recAttrAttr2-&#62;u_32_value(),
  psop-&#62;get_range_no());
}
psop-&#62;close();</pre>
<p>When run, this code produces the following output:</p>
<pre>SUB_ID    COUNTRY_CODE
2           1   Range no :  0
7          46   Range no :  1
8           1   Range no :  1
9          44   Range no :  1
13          1   Range no :  2</pre>
<h3>Why is this signifficant?</h3>
<p>This can be very useful for applications using the NDB API; imagine an application that wanted to find the birthdays for all of my friends. Assume that I have 2 tables of interest:</p>
<pre>mysql&#62; describe friends; describe birthday;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| name   | varchar(30) | NO   | PRI | NULL    |       |
| friend | varchar(30) | NO   | PRI |         |       |
+--------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(30) | NO   | PRI | NULL    |       |
| day   | int(11)     | YES  |     | NULL    |       |
| month | int(11)     | YES  |     | NULL    |       |
| year  | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)</pre>
<p>Using the NDB API, I can create 1 NdbIndexScanOperation operation to read all tuples from &#8220;friends&#8221; where the &#8220;name&#8221; field matches &#8220;Andrew&#8221; and then use the results to perform a second NdbIndexScanOperation to read the rows that match each of my friends&#8217; names in the &#8220;birthday&#8221; table. In other words, performing a join using only 2 trips from the application to the data nodes.</p>
<p>
Of course, it&#8217;s simple to get the same results using SQL&#8230;<code>SELECT birthday.name, birthday.day, birthday.month FROM friends, birthday WHERE friend.name='Andrew' AND friends.friend=birthday.name;</code><strong>However</strong>, if the tables are very large and I have a lot of friends then performing this join using SQL can be expensive as it requires a separate trip to the data nodes to fetch each birthday. In the future, Batched Key Access (BKA) will optimise these joins by performing one of these NDB API Multi-Range Reads (MRR) to fetch all of the birthdays in one go!  Until then, using the NDB API directly can deliver signifficantly faster results.</p>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 20:12:26 +0000</pubDate>
    <dc:creator>Andrew Morgan</dc:creator>
    <category>MySQL Cluster</category>
    <category>Batched-Key Access</category>
    <category>BKA</category>
    <category>MRR</category>
    <category>Multi-Range Read</category>
    <category>MySQL</category>
    <category>MySQL Cluster CGE</category>
  </item>

  <item>
    <title>[MySQL][VP]Vertical Partitioning storage engine 0.2 released</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-7870178081855084823.post-3160793584581567228</guid>
    <link>http://wild-growth.blogspot.com/2009/07/mysqlvpvertical-partitioning-storage.html</link>
    <description>I'm pleased to announce the release of Vertical Partitioning storage engine version 0.2.http://launchpad.net/vpformysqlThe main changes in this version are following.- Support MySQL's table partitioning.&amp;nbsp;&amp;nbsp;MySQL's table partitioning that is only introduced last release is now supported.&amp;nbsp;&amp;nbsp;note: After this version, you need to apply a patch for installing Vertical Partitioning storage engine.- After this version, the primary key part of InnoDB's secondary index is effectively used.&amp;nbsp;&amp;nbsp;You can use the primary key columns with InnoDB's secondary index by using following statements.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;create table tbl_b(&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_a int not null,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_b varchar(20),&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_c int not null,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;primary key(col_a),&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key idx1(col_c)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)engine=InnoDB;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;create table tbl_c(&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_a int not null,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_b varchar(20),&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_c int not null,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;primary key(col_a),&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key idx1(col_c)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)engine=InnoDB;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;create table tbl_a(&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_a int not null,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_b varchar(20),&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;col_c int not null,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;primary key(col_a),&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key idx1(col_c, col_a)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)engine=VP comment='table_name_list &quot;tbl_b tbl_c&quot;';&amp;nbsp;&amp;nbsp;note: Vertical Partitioning storage engine can use index with primary key together with index without primary key, because Vertical Partitioning storage engine can use different storage engines for child tables at same table. In this case, the purpose of writing the column of primary key to tbl_a's idx1 is to absorb the difference by this coexistence.Please see &quot;99_change_logs.txt&quot; in the download documents for checking other changes.Enjoy!</description>
    <content:encoded><![CDATA[I'm pleased to announce the release of Vertical Partitioning storage engine version 0.2.<br />http://launchpad.net/vpformysql<br /><br /><br />The main changes in this version are following.<br /><br /><br />- Support MySQL's table partitioning.<br />&nbsp;&nbsp;MySQL's table partitioning that is only introduced <a href="http://wild-growth.blogspot.com/2009/06/mysqlvpvertical-partitioning-storage.html">last release</a> is now supported.<br />&nbsp;&nbsp;note: After this version, you need to apply a patch for installing Vertical Partitioning storage engine.<br /><br />- After this version, the primary key part of InnoDB's secondary index is effectively used.<br />&nbsp;&nbsp;You can use the primary key columns with InnoDB's secondary index by using following statements.<br />&nbsp;&nbsp;&nbsp;&nbsp;create table tbl_b(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_a int not null,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_b varchar(20),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_c int not null,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;primary key(col_a),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key idx1(col_c)<br />&nbsp;&nbsp;&nbsp;&nbsp;)engine=InnoDB;<br />&nbsp;&nbsp;&nbsp;&nbsp;create table tbl_c(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_a int not null,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_b varchar(20),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_c int not null,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;primary key(col_a),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key idx1(col_c)<br />&nbsp;&nbsp;&nbsp;&nbsp;)engine=InnoDB;<br />&nbsp;&nbsp;&nbsp;&nbsp;create table tbl_a(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_a int not null,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_b varchar(20),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col_c int not null,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;primary key(col_a),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key idx1(col_c, col_a)<br />&nbsp;&nbsp;&nbsp;&nbsp;)engine=VP comment='table_name_list "tbl_b tbl_c"';<br />&nbsp;&nbsp;note: Vertical Partitioning storage engine can use index with primary key together with index without primary key, because Vertical Partitioning storage engine can use different storage engines for child tables at same table. In this case, the purpose of writing the column of primary key to tbl_a's idx1 is to absorb the difference by this coexistence.<br /><br /><br />Please see "99_change_logs.txt" in the download documents for checking other changes.<br /><br />Enjoy!<div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7870178081855084823-3160793584581567228?l=wild-growth.blogspot.com" /></div>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 17:17:00 +0000</pubDate>
    <dc:creator>Kentoku SHIBA</dc:creator>
    <category>VP</category>
    <category>MySQL</category>
  </item>

  <item>
    <title>Benchmarking Drizzle with MyBench(DBD::drizzle)</title>
    <guid isPermaLink="false">http://ronaldbradford.com/blog/?p=1707</guid>
    <link>http://ronaldbradford.com/blog/benchmarking-drizzle-with-mybenchdbddrizzle-2009-07-01/</link>
    <description>With thanks to  Patrick Galbraith and his DBD::drizzle 0.200 I am now able to test client benchmarks side by side with MySQL and Drizzle.
For simple benchmarking with clients, generally when I have little time, I use a simple Perl framework mybench. I was able to change just the connection string and run tests.
The diff of my two scripts where:

---
&gt; my $user      = $opt{u} || &quot;appuser&quot;;
&gt; my $pass      = $opt{p} || &quot;password&quot;;
&gt; my $port      = $opt{P} || 3306;
&gt; my $dsn       = &quot;DBI:mysql:$db:$host;port=$port&quot;;
---
&lt; my $user      = $opt{u} || &quot;root&quot;;
&lt; my $pass      = $opt{p} || &quot;&quot;;
&lt; my $port      = $opt{P} || 4427;
&lt; my $dsn       = &quot;DBI:drizzle:$db:$host;port=$port&quot;;
---

It&amp;#8217;s too early to tell what improvement Drizzle will make. Just running my first test with single and multi thread tests shows an improvement in all figures in Drizzle via MySQL, however I will need to run this on various different versions of MySQL including the latest 5.0 to confirm.
</description>
    <content:encoded><![CDATA[<p>With thanks to  Patrick Galbraith and his <a href="http://capttofu.livejournal.com/19704.html">DBD::drizzle 0.200</a> I am now able to test client benchmarks side by side with MySQL and Drizzle.</p>
<p>For simple benchmarking with clients, generally when I have little time, I use a simple Perl framework <a href="http://jeremy.zawodny.com/mysql/mybench/">mybench</a>. I was able to change just the connection string and run tests.</p>
<p>The diff of my two scripts where:</p>
<pre>
---
> my $user      = $opt{u} || "appuser";
> my $pass      = $opt{p} || "password";
> my $port      = $opt{P} || 3306;
> my $dsn       = "DBI:mysql:$db:$host;port=$port";
---
< my $user      = $opt{u} || "root";
< my $pass      = $opt{p} || "";
< my $port      = $opt{P} || 4427;
< my $dsn       = "DBI:drizzle:$db:$host;port=$port";
---
</pre>
<p>It&#8217;s too early to tell what improvement Drizzle will make. Just running my first test with single and multi thread tests shows an improvement in all figures in Drizzle via MySQL, however I will need to run this on various different versions of MySQL including the latest 5.0 to confirm.</p>
</pre>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 17:13:37 +0000</pubDate>
    <dc:creator>Ronald Bradford</dc:creator>
    <category>Databases</category>
    <category>Drizzle</category>
    <category>General</category>
    <category>MySQL</category>
    <category>Open Source</category>
    <category>Professional</category>
  </item>

  <item>
    <title>JFS and RHEL5</title>
    <guid isPermaLink="false">http://themattreid.com/wordpress/?p=192</guid>
    <link>http://feedproxy.google.com/~r/Themattreid/~3/JsYp2j55THg/</link>
    <description>Quick one here; If you&amp;#8217;re thinking to yourself &amp;#8220;why can&amp;#8217;t I make the MySQL data partition JFS on my RHEL5 server&amp;#8230;&amp;#8221; here&amp;#8217;s a good how to: http://phaq.phunsites.net/2008/02/04/enabling-reiserfs-xfs-jfs-on-redhat-enterprise-linux/
</description>
    <content:encoded><![CDATA[<p>Quick one here; If you&#8217;re thinking to yourself &#8220;why can&#8217;t I make the MySQL data partition JFS on my RHEL5 server&#8230;&#8221; here&#8217;s a good how to: <a title="http://phaq.phunsites.net/2008/02/04/enabling-reiserfs-xfs-jfs-on-redhat-enterprise-linux/" href="http://phaq.phunsites.net/2008/02/04/enabling-reiserfs-xfs-jfs-on-redhat-enterprise-linux/" target="_blank">http://phaq.phunsites.net/2008/02/04/enabling-reiserfs-xfs-jfs-on-redhat-enterprise-linux/</a></p>
<img src="http://feeds.feedburner.com/~r/Themattreid/~4/JsYp2j55THg" height="1" width="1" />]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 16:17:00 +0000</pubDate>
    <dc:creator>Matt Reid</dc:creator>
    <category>General</category>
    <category>filesystems</category>
    <category>jfs</category>
  </item>

  <item>
    <title>xtrabackup-0.8</title>
    <guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=709</guid>
    <link>http://www.mysqlperformanceblog.com/2009/07/01/xtrabackup-08/</link>
    <description>Dear community,
The release 0.8 of the opensource backup tool for InnoDB and XtraDB is available for download.
Key features:

New mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
Experimental option --export is added (see Vadim's post &quot;Impossible - possible, moving InnoDB tables between servers&quot;for details)

tar4ibd is made to be sure that read of InnoDB page is consistent. Before we had some complains what in stream mode some pages are getting corrupted, and we suspect tar can do read of  pages in time when they changed. So we patches libtar to make read consistent.
Export is added to support moving .ibd tablespaces between servers.
The list of other features in the release includes:

Support of ARCHIVE tables
Addded incremental option to innobackupex-1.5.1 script
Rollback XA PREPAREd transaction automatically at --prepare
To extend tablespace size, if needed after --prepare
Data page corruption check is added to local backup mode
innobackupex can pass --export option
Bug #389360: innobackupex-1.5.1 accepts scp options

Fixed bugs:

Bug #388062: Update to innobackupex to include incremental
fix error handling of tar stream

The binary packages for RHEL4,5, Debian, FreeBSD as well as source code of the XtraBackup is available on http://www.percona.com/mysql/xtrabackup/0.8/.
The project lives on Launchpad : https://launchpad.net/percona-xtrabackup and you can report bug to Launchpad bug system:
https://launchpad.net/percona-xtrabackup/+filebug. The documentation is available on our Wiki.
For general questions use our Pecona-discussions group, and for development question Percona-dev group.
For support, commercial and sponsorship inquiries contact Percona.
    
    Entry posted by Aleksandr Kuzminsky |
      6 comments
    Add to:  |  |  |  | </description>
    <content:encoded><![CDATA[<p>Dear community,</p>
<p>The release 0.8 of the opensource backup tool for InnoDB and XtraDB is available for <a href="http://www.percona.com/mysql/xtrabackup/0.8/" target="_blank">download</a>.</p>
<p>Key features:</p>
<ul>
<li>New mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11</li>
<li>Experimental option --export is added (see Vadim's post <a rel="bookmark" href="http://www.mysqlperformanceblog.com/2009/07/01/2009/06/08/impossible-possible-moving-innodb-tables-between-servers/">"Impossible - possible, moving InnoDB tables between servers"</a>for details)</li>
</ul>
<p>tar4ibd is made to be sure that read of InnoDB page is consistent. Before we had some complains what in stream mode some pages are getting corrupted, and we suspect tar can do read of  pages in time when they changed. So we patches libtar to make read consistent.</p>
<p>Export is added to support moving .ibd tablespaces between servers.</p>
<p>The list of other features in the release includes:</p>
<ul>
<li>Support of ARCHIVE tables</li>
<li>Addded incremental option to innobackupex-1.5.1 script</li>
<li>Rollback XA PREPAREd transaction automatically at --prepare</li>
<li>To extend tablespace size, if needed after --prepare</li>
<li>Data page corruption check is added to local backup mode</li>
<li>innobackupex can pass --export option</li>
<li><a href="https://bugs.launchpad.net/percona-xtrabackup/+bug/389360">Bug #389360:</a> innobackupex-1.5.1 accepts scp options</li>
</ul>
<p>Fixed bugs:</p>
<ul>
<li><a href="https://bugs.launchpad.net/percona-xtrabackup/+bug/388062">Bug #388062:</a> Update to innobackupex to include incremental</li>
<li>fix error handling of tar stream</li>
</ul>
<p>The binary packages for RHEL4,5, Debian, FreeBSD as well as source code of the XtraBackup is available on <a href="http://www.percona.com/mysql/xtrabackup/0.8/">http://www.percona.com/mysql/xtrabackup/0.8/</a>.</p>
<p>The project lives on Launchpad : <a href="https://launchpad.net/percona-xtrabackup">https://launchpad.net/percona-xtrabackup</a> and you can report bug to Launchpad bug system:<br />
<a href="https://launchpad.net/percona-xtrabackup/+filebug">https://launchpad.net/percona-xtrabackup/+filebug</a>. The documentation is available on <a href="http://www.percona.com/docs/wiki/percona-xtrabackup:start">our Wiki</a>.</p>
<p>For general questions use our <a href="http://groups.google.com/group/percona-discussion">Pecona-discussions</a> group, and for development question <a href="http://groups.google.com/group/percona-dev">Percona-dev</a> group.</p>
<p>For support, commercial and sponsorship inquiries contact <a href="http://www.percona.com/contacts.html">Percona</a>.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Aleksandr Kuzminsky |
      <a href="http://www.mysqlperformanceblog.com/2009/07/01/xtrabackup-08/#comments">6 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/07/01/xtrabackup-08/&amp;title=xtrabackup-0.8" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/07/01/xtrabackup-08/&amp;title=xtrabackup-0.8" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/07/01/xtrabackup-08/&amp;title=xtrabackup-0.8" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/07/01/xtrabackup-08/&amp;T=xtrabackup-0.8" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/07/01/xtrabackup-08/&amp;title=xtrabackup-0.8" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 15:09:04 +0000</pubDate>
    <dc:creator>MySQL Performance Blog</dc:creator>
    <category>Backups</category>
  </item>

  <item>
    <title>OpenSQL Camp 2009: List of current session proposals; keep them coming!</title>
    <guid isPermaLink="false">http://www.lenzg.net/archives/269-guid.html</guid>
    <link>http://www.lenzg.net/archives/269-OpenSQL-Camp-2009-List-of-current-session-proposals;-keep-them-coming!.html</link>
    <description>I've now posted all the current talk submissions to the OpenSQL Camp Wiki. A big Thank You to everyone who contributed so far and helped us to bang the drum for this event! If you haven't heard about OpenSQL Camp yet, it's a subconference of the Free and Open Source Conference (FrOSCon) in St. Augustin, Germany, which takes place on August 22+23. The topic of OpenSQL Camp is &quot;Open Source databases and related technologies&quot; and we're looking for interesting presentations in this field.

As we have 12 session slots to fill, we still have room for at least 6 more submissions! It's also a tad bit MySQL-centric at the moment, that should definitely change! We would love to get some more diversity to cover a broader range of Open Source Database technology.

So please submit your talk proposals and help spreading the word &amp;mdash; the Call for Papers is still open until July, 19th! Post a message to relevant discussion forums and mailing lists. Know an expert in this field? Approach him directly! OpenSQL Camp Speakers will receive free entry to FrOSCon, which is worth visiting in any case!</description>
    <content:encoded><![CDATA[<p>I've now posted all the current talk submissions to the <a href="http://opensqlcamp.org/Events/2009/Proposed_Sessions" title="OpenSQL Camp talk submission">OpenSQL Camp Wiki</a>. A big Thank You to everyone who contributed so far and helped us to bang the drum for this event! If you haven't heard about OpenSQL Camp yet, it's a subconference of the Free and Open Source Conference (<a href="http://froscon.org/">FrOSCon</a>) in St. Augustin, Germany, which takes place on August 22+23. The topic of OpenSQL Camp is "Open Source databases and related technologies" and we're looking for interesting presentations in this field.</p>

<p>As we have 12 session slots to fill, we still have room for at least 6 more submissions! It's also a tad bit MySQL-centric at the moment, that should definitely change! We would love to get some more diversity to cover a broader range of Open Source Database technology.</p>

<p>So please submit your talk proposals and help spreading the word &mdash; the <a href="  http://opensqlcamp.org/Events/2009/Call_for_Participation" title="OpenSQL Camp Call for Papers">Call for Papers</a> is still open until July, 19th! Post a message to relevant discussion forums and mailing lists. Know an expert in this field? Approach him directly! OpenSQL Camp Speakers will receive free entry to FrOSCon, which is worth visiting in any case!</p>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 15:00:51 +0000</pubDate>
    <dc:creator>Lenz Grimmer</dc:creator>
    <category>Linux</category>
    <category>MySQL</category>
    <category>OSS</category>
    <category>collaborating</category>
    <category>community</category>
    <category>conference</category>
    <category>contributing</category>
    <category>databases</category>
    <category>event</category>
    <category>froscon</category>
    <category>mysql</category>
    <category>opensqlcamp</category>
    <category>oss</category>
    <category>wiki</category>
  </item>

  <item>
    <title>Status 96 error on svc.startd</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-6857743382661795219.post-4431788246149061284</guid>
    <link>http://csylvester.blogspot.com/2009/07/status-96-error-on-svcstartd.html</link>
    <description>I've been working with SMF on and off for a few weeks now and still get stung by this error. If you see something like this in the SVC log after enabling a service (i.e., svcadm enable mysql):bash-3.00# cat  /var/svc/log/application-database-mysql:v51.log[ Jul  1 07:36:37 Enabled. ][ Jul  1 07:36:37 Executing start method (&quot;/lib/svc/method/mysql start&quot;) ]svc.startd could not set context for method: chdir: No such file or directory[ Jul  1 07:36:37 Method &quot;start&quot; exited with status 96 ]head over to the manifest file for the service and check the method_context section. In my case, I had no working_directory element set so adding this element solves the problem.Before:&amp;lt;method_context&amp;gt;    &amp;lt;method_credential user='mysql' group='mysql' /&amp;gt;&amp;lt;/method_context&amp;gt;After:&amp;lt;method_context working_directory='/usr/local/mysql'&amp;gt;    &amp;lt;method_credential user='mysql' group='mysql' /&amp;gt;&amp;lt;/method_context&amp;gt;After making this change, don't forget to import the manifest:svccfg import /var/svc/manifest/application/database/mysql.xml-- Craig</description>
    <content:encoded><![CDATA[I've been working with SMF on and off for a few weeks now and still get stung by this error. If you see something like this in the SVC log after enabling a service (i.e., <i>svcadm enable mysql</i>):<br /><br /><blockquote><span>bash-3.00# cat  /var/svc/log/application-database-mysql:v51.log<br />[ Jul  1 07:36:37 Enabled. ]<br />[ Jul  1 07:36:37 Executing start method ("/lib/svc/method/mysql start") ]<br />svc.startd could not set context for method: chdir: No such file or directory<br />[ Jul  1 07:36:37 Method "start" exited with status 96 ]</span></blockquote><br /><br />head over to the manifest file for the service and check the <span>method_context</span> section. In my case, I had no working_directory element set so adding this element solves the problem.<br /><br />Before:<br /><blockquote><span><br /><pre>&lt;method_context&gt;<br />    &lt;method_credential user='mysql' group='mysql' /&gt;<br />&lt;/method_context&gt;</pre></span></blockquote><br />After:<br /><blockquote><span><br /><pre>&lt;method_context <span>working_directory='/usr/local/mysql'</span>&gt;<br />    &lt;method_credential user='mysql' group='mysql' /&gt;<br />&lt;/method_context&gt;</pre></span></blockquote><br />After making this change, don't forget to import the manifest:<br /><blockquote><span>svccfg import /var/svc/manifest/application/database/mysql.xml</span></blockquote><br /><br />-- Craig<div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/6857743382661795219-4431788246149061284?l=csylvester.blogspot.com" /></div>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 14:34:00 +0000</pubDate>
    <dc:creator>Craig Sylvester</dc:creator>
  </item>

  <item>
    <title>SquashFS errors during FC11 install</title>
    <guid isPermaLink="false">924 at http://www.krisbuytaert.be/blog</guid>
    <link>http://www.krisbuytaert.be/blog/squashfs-errors-during-fc11-install</link>
    <description>My FC10 to FC11 yum upgrade got stuck on a zillion dependencies .. well actually libssl and mysql from Remi .. but from there it's a whole chain of other things.  So I had the great idea to go for the F11 Live CD,   the LiveCD works like a charm,, only upon trying to install the live CD to my OS partition it started failing on me with a bunch of squashfs errors  ,
It really looks like this F11Beta blocking issue  which apparently didn't get solved completely after all..  the annoying part is that I can't reproduce the issue anymore .. as my system is now fully working .. maybe on my office desktop next week :)
Oh well.. the full DVD ISO got downloaded and burned and now I can once again enjoy the annoyancies of a freshly installed distro, missing packages, configs that have lightly chaged etc :)   Wonder if sound is working out of the box now :)
Update:  It works .. partly ... (no sound in firefox it seems atm..)
Technorati Tags: fc11 live install squashfs  Share with Shareomatic! 



  Trackback URL for this post:

  http://www.krisbuytaert.be/blog/trackback/924

</description>
    <content:encoded><![CDATA[<p>My FC10 to FC11 yum upgrade got stuck on a zillion dependencies .. well actually libssl and mysql from Remi .. but from there it's a whole chain of other things.  So I had the great idea to go for the F11 Live CD,   the LiveCD works like a charm,, only upon trying to install the live CD to my OS partition it started failing on me with a bunch of squashfs errors  ,</p>
<p>It really looks like <a href="https://bugzilla.redhat.com/show_bug.cgi?id=489698">this</a> F11Beta blocking issue  which apparently didn't get solved completely after all..  the annoying part is that I can't reproduce the issue anymore .. as my system is now fully working .. maybe on my office desktop next week :)</p>
<p>Oh well.. the full DVD ISO got downloaded and burned and now I can once again enjoy the annoyancies of a freshly installed distro, missing packages, configs that have lightly chaged etc :)   Wonder if sound is working out of the box now :)</p>
<p>Update:  It works .. partly ... (no sound in firefox it seems atm..)</p>
<div><img alt="Technorati Tags:" src="http://www.krisbuytaert.be/blog/sites/all/modules/technorati/technobubble.gif" /><strong>Technorati Tags: </strong><a href="http://technorati.com/tag/fc11" rel="tag">fc11</a> <a href="http://technorati.com/tag/live+install" rel="tag">live install</a> <a href="http://technorati.com/tag/squashfs" rel="tag">squashfs</a></div><div> <a href="http://www.shareomatic.com/http://www.krisbuytaert.be/blog/squashfs-errors-during-fc11-install/shareomatic-drupal/SquashFS errors during FC11 install"><img src="http://www.shareomatic.com/images/s_16_black.gif" alt="Share with Shareomatic!" title="Post this item on various social news sites with Shareomatic!" /></a> <a href="http://www.shareomatic.com/http://www.krisbuytaert.be/blog/squashfs-errors-during-fc11-install/shareomatic-drupal/SquashFS errors during FC11 install">Share with Shareomatic!</a> </div>
<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description rdf:about="http://www.krisbuytaert.be/blog/squashfs-errors-during-fc11-install" dc:identifier="http://www.krisbuytaert.be/blog/squashfs-errors-during-fc11-install" dc:title="SquashFS errors during FC11 install" trackback:ping="http://www.krisbuytaert.be/blog/trackback/924" />
</rdf:RDF>
-->
<div><div>

  <h3>Trackback URL for this post:</h3>

  <div>http://www.krisbuytaert.be/blog/trackback/924</div>
</div>
</div>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 14:08:18 +0000</pubDate>
    <dc:creator>Kris Buytaert</dc:creator>
    <category>fc11</category>
    <category>live install</category>
    <category>squashfs</category>
  </item>

  <item>
    <title>Good Practice / Bad Practice: Off-site Backups</title>
    <guid isPermaLink="false">http://openquery.com/blog/?p=796</guid>
    <link>http://openquery.com/blog/good-practice-bad-practice-offsite-backups</link>
    <description>In today&amp;#8217;s gp/bp an open door will be kicked in: take your backups offsite!
I was actually tempted to create a poll to see how many of you do not have proper backups, and how many of you do not take those backups offsite. It is a simple piece of advice and relatively simple to set up. Offsite in this case would ideally be physically offsite: to a different server in a different building in a different location. A start however is to take them to a different server. And don&amp;#8217;t make the mistake of thinking a different VPS on the same physical server is good enough. True, that will protect you from operating system failure of the guest, but it will likely not protect you from hardware failure, or operating system failure on the host OS.
Also, take good care of how you are getting your backups offsite. A normal FTP connection might do the job, but it is hardly secure. Ideally, use SFTP or rsync over ssh to stream your backups offsite.
Some people still take their backups offsite by physically moving a cd, dvd or tape from one location to another. It&amp;#8217;s a good start, but in this age of cheap broadband, you might want to think about doing this online. A cron-job is much less likely to not run than it is for you to forget to move that tape.
In our good practice / bad practice series, we will provide you with byte/bite sized pieces of advice on what we consider good (or bad) practice in MySQL-land. The topics can be just about anything, so expect random things to come up. Also, the level of advancedness greatly varies. A topic might be a no-brainer for some, a reminder for others and a revelation for a third person. We strive to tender to all of you!
</description>
    <content:encoded><![CDATA[<p>In today&#8217;s gp/bp an open door will be kicked in: take your backups offsite!<br />
I was actually tempted to create a poll to see how many of you do not have proper backups, and how many of you do not take those backups offsite. It is a simple piece of advice and relatively simple to set up. Offsite in this case would ideally be physically offsite: to a different server in a different building in a different location. A start however is to take them to a different server. And don&#8217;t make the mistake of thinking a different VPS on the same physical server is good enough. True, that will protect you from operating system failure of the guest, but it will likely not protect you from hardware failure, or operating system failure on the host OS.</p>
<p>Also, take good care of how you are getting your backups offsite. A normal FTP connection might do the job, but it is hardly secure. Ideally, use SFTP or rsync over ssh to stream your backups offsite.<br />
Some people still take their backups offsite by physically moving a cd, dvd or tape from one location to another. It&#8217;s a good start, but in this age of cheap broadband, you might want to think about doing this online. A cron-job is much less likely to not run than it is for you to forget to move that tape.</p>
<p><em>In our good practice / bad practice series, we will provide you with byte/bite sized pieces of advice on what we consider good (or bad) practice in MySQL-land. The topics can be just about anything, so expect random things to come up. Also, the level of advancedness greatly varies. A topic might be a no-brainer for some, a reminder for others and a revelation for a third person. We strive to tender to all of you!<br />
</em></p>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 13:51:57 +0000</pubDate>
    <dc:creator>Open Query</dc:creator>
    <category>Good practice / Bad practice</category>
    <category>backup</category>
    <category>mysql</category>
    <category>offsite</category>
  </item>

  <item>
    <title>MySQLi result set iteration - recursive</title>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/114-guid.html</guid>
    <link>http://schlueters.de/blog/archives/114-MySQLi-result-set-iteration-recursive.html</link>
    <description>PHP 5.3 is released and after the release stress is over my mind is open for new ideas. While relaxing yesterday I thought about many things, among them was the Resultset iterator I recently discussed.Now I wondered where to go next with this and had the idea that an individual Resultset is a child of the whole result and this might be wrapped in an Recursive Iterator. For doing so we don't implement the Iterator interface but RecursiveIterator. RecursiveIterator extends a typical Iterator with two methods: hasChildren() and getChildren(). But now we have a problem: The Iterator returned by getChildren() has to be a RecursiveIterator, too, which makes sense, in general. But I want to return a MySQLi Resultset which isn't recursive - so making this a RecursiveIterator is wrong. My solution now is to introduce yet another Iterator which goes by the name of MySQLi_PseudoRecursiveResultIterator and is implemented by extending IteratorIterator which will wrap the MySQLi_Result and implements RecursiveIterator telling the caller that there are no children.As a sidenote: In our experimental tree Andrey made MySQLi_Result an iterator but that's not yet in php.net's CVS (might need some more testing, and probably we might change the design there...) so I'm emulating this with MySQLi_Result::fetch_all() combined with an ArrayIterator, using the experimental code the constructor can be dropped.So let's finally look at the code of these two classes:
&amp;lt;?php
class MySQLi_ResultsetIterator implements RecursiveIterator
{
    private $mysqli;
    private $counter = 0;
    private $current = null;
    private $rewinded = false;

    public function __construct(mysqli $mysqli) {
        $this-&amp;gt;mysqli = $mysqli;
    }
    private function freeCurrent() {
        if ($this-&amp;gt;current) {
            $this-&amp;gt;current-&amp;gt;free();
            $this-&amp;gt;current = null;
        }
    }
    public function rewind() {
        if ($this-&amp;gt;rewinded) {
            throw new Exception(&amp;quot;Already rewinded&amp;quot;);
        }
        $this-&amp;gt;freeCurrent();
        $this-&amp;gt;counter = 0;
        $this-&amp;gt;rewinded = true;
    }
    public function valid() {
        $this-&amp;gt;current = $this-&amp;gt;mysqli-&amp;gt;store_result();
        return (bool)$this-&amp;gt;current;
    }
    public function next() {
        $this-&amp;gt;freeCurrent();
        $this-&amp;gt;counter++;
        $this-&amp;gt;mysqli-&amp;gt;next_result();
    }
    public function key() {
        return $this-&amp;gt;counter;
    }
    public function current() {
        if (!$this-&amp;gt;current) {
            throw new Exception(&amp;quot;valid() not called&amp;quot;);
        }
        return $this-&amp;gt;current;
    }

    public function hasChildren() {
        return true;
    }
    public function getChildren() {
        return new MySQLi_PseudoRecursiveResultIterator($this-&amp;gt;current);
    }
}

class MySQLi_PseudoRecursiveResultIterator
     extends IteratorIterator
     implements RecursiveIterator
{
    public function __construct(MySQLi_Result $result) {
        // This ctor can be dropped with the experimental bzr sources
        // as IteratorIterator::__construct() directly works with
        // MySQLi_Result
        parent::__construct(new ArrayIterator($result-&amp;gt;fetch_all()));
    }
    public function hasChildren() {
        return false;
    }
    public function getChildren() {
        throw new Exception(&amp;quot;This should never be called&amp;quot;);
    }    
}
?&amp;gt;
Now we can use this code. For properly using a RecursiveIterator one should use a RecursiveIteratorIterator (RII). To get some nice labels I'm extending the RII and then have a single foreach:
&amp;lt;?php
class MyRecursive_IteratorIterator
     extends RecursiveIteratorIterator
{
    public function __construct(MySQLi $mysqli, $flags = 0) {
        parent::__construct(
                new Mysqli_ResultSetIterator($mysqli),
                $flags | RecursiveIteratorIterator::LEAVES_ONLY);
    }

    public function beginChildren() {
        echo &amp;quot;Next ResultSet:\n&amp;quot;;
    }
}

$mysqli = new MySQLi(&amp;quot;localhost&amp;quot;, &amp;quot;root&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;test&amp;quot;);

$query  = &amp;quot;SELECT 1,2 UNION SELECT 3, 4;&amp;quot;.
          &amp;quot;SELECT 'hi world' UNION SELECT 'foobar'&amp;quot;;
if ($mysqli-&amp;gt;multi_query($query)) {
    foreach (new MyRecursive_IteratorIterator($mysqli) as $key =&amp;gt; $row) {
        printf(&amp;quot;    %s\n&amp;quot;, $row[0]);
    }
}
?&amp;gt;

Now calling this code gives us a result similar to the following:
Next ResultSet:
    1
    3
Next ResultSet:
    hi world
    foobar
Isn't that nice? - I think that's a cool API! What do you think? Do you have use cases for such an API? Should we implement this in C and bundle it with PHP? Any feedback welcome!</description>
    <content:encoded><![CDATA[<p>PHP 5.3 is released and after the release stress is over my mind is open for new ideas. While relaxing yesterday I thought about many things, among them was the Resultset iterator <a href="http://schlueters.de/blog/archives/112-MySQLi-Resultset-Iterator.html">I recently discussed</a>.</p><p>Now I wondered where to go next with this and had the idea that an individual Resultset is a child of the whole result and this might be wrapped in an Recursive Iterator. For doing so we don't implement the Iterator interface but RecursiveIterator. RecursiveIterator extends a typical Iterator with two methods: hasChildren() and getChildren(). But now we have a problem: The Iterator returned by getChildren() has to be a RecursiveIterator, too, which makes sense, in general. But I want to return a MySQLi Resultset which isn't recursive - so making this a RecursiveIterator is wrong. My solution now is to introduce yet another Iterator which goes by the name of MySQLi_PseudoRecursiveResultIterator and is implemented by extending IteratorIterator which will wrap the MySQLi_Result and implements RecursiveIterator telling the caller that there are no children.</p><p>As a sidenote: In <a href="https://code.launchpad.net/php-mysqlnd">our experimental tree</a> <a href="http://hristov.com/oblog/">Andrey</a> made MySQLi_Result an iterator but that's not yet in php.net's CVS (might need some more testing, and probably we might change the design there...) so I'm emulating this with MySQLi_Result::fetch_all() combined with an ArrayIterator, using the experimental code the constructor can be dropped.</p><p>So let's finally look at the code of these two classes:</p>
<pre>&lt;?php
class MySQLi_ResultsetIterator implements RecursiveIterator
{
    private $mysqli;
    private $counter = 0;
    private $current = null;
    private $rewinded = false;

    public function __construct(mysqli $mysqli) {
        $this-&gt;mysqli = $mysqli;
    }
    private function freeCurrent() {
        if ($this-&gt;current) {
            $this-&gt;current-&gt;free();
            $this-&gt;current = null;
        }
    }
    public function rewind() {
        if ($this-&gt;rewinded) {
            throw new Exception(&quot;Already rewinded&quot;);
        }
        $this-&gt;freeCurrent();
        $this-&gt;counter = 0;
        $this-&gt;rewinded = true;
    }
    public function valid() {
        $this-&gt;current = $this-&gt;mysqli-&gt;store_result();
        return (bool)$this-&gt;current;
    }
    public function next() {
        $this-&gt;freeCurrent();
        $this-&gt;counter++;
        $this-&gt;mysqli-&gt;next_result();
    }
    public function key() {
        return $this-&gt;counter;
    }
    public function current() {
        if (!$this-&gt;current) {
            throw new Exception(&quot;valid() not called&quot;);
        }
        return $this-&gt;current;
    }

    public function hasChildren() {
        return true;
    }
    public function getChildren() {
        return new MySQLi_PseudoRecursiveResultIterator($this-&gt;current);
    }
}

class MySQLi_PseudoRecursiveResultIterator
     extends IteratorIterator
     implements RecursiveIterator
{
    public function __construct(MySQLi_Result $result) {
        // This ctor can be dropped with the experimental bzr sources
        // as IteratorIterator::__construct() directly works with
        // MySQLi_Result
        parent::__construct(new ArrayIterator($result-&gt;fetch_all()));
    }
    public function hasChildren() {
        return false;
    }
    public function getChildren() {
        throw new Exception(&quot;This should never be called&quot;);
    }    
}
?&gt;</pre>
<p>Now we can use this code. For properly using a RecursiveIterator one should use a RecursiveIteratorIterator (RII). To get some nice labels I'm extending the RII and then have a single foreach:</p>
<pre>&lt;?php
class MyRecursive_IteratorIterator
     extends RecursiveIteratorIterator
{
    public function __construct(MySQLi $mysqli, $flags = 0) {
        parent::__construct(
                new Mysqli_ResultSetIterator($mysqli),
                $flags | RecursiveIteratorIterator::LEAVES_ONLY);
    }

    public function beginChildren() {
        echo &quot;Next ResultSet:\n&quot;;
    }
}

$mysqli = new MySQLi(&quot;localhost&quot;, &quot;root&quot;, &quot;&quot;, &quot;test&quot;);

$query  = &quot;SELECT 1,2 UNION SELECT 3, 4;&quot;.
          &quot;SELECT 'hi world' UNION SELECT 'foobar'&quot;;
if ($mysqli-&gt;multi_query($query)) {
    foreach (new MyRecursive_IteratorIterator($mysqli) as $key =&gt; $row) {
        printf(&quot;    %s\n&quot;, $row[0]);
    }
}
?&gt;
</pre>
<p>Now calling this code gives us a result similar to the following:</p>
<pre>Next ResultSet:
    1
    3
Next ResultSet:
    hi world
    foobar</pre>
<p>Isn't that nice? - I think that's a cool API! What do you think? Do you have use cases for such an API? Should we implement this in C and bundle it with PHP? Any feedback welcome!</p>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 09:56:59 +0000</pubDate>
    <dc:creator>Johannes Schl&amp;uuml;ter</dc:creator>
    <category>MySQL</category>
    <category>PHP</category>
    <category>coding</category>
    <category>iterator</category>
    <category>mysql</category>
    <category>mysqli</category>
    <category>php</category>
    <category>resultset</category>
    <category>stored procedures</category>
  </item>

  <item>
    <title>Problems with .FRM files, auto-discovery and MySQL Cluster</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-19281624.post-4755810924004513326</guid>
    <link>http://johanandersson.blogspot.com/2009/07/problems-with-frm-files-auto-discovery.html</link>
    <description>There are some bug reports on the auto-discovery protocol in MySQL Cluster.The idea of the auto-discovery protocol is to fetch the .frm files for the NDB tables stored in the data dictionary of the data nodes, and put them in the data directory of the mysql server.However, sometimes (not always, which makes it more difficult to reproduce and hence fix), the auto-discovery seems to make strange things (from this bug report):After shuting down and restoring my cluster I get the following error.090211  9:59:26 [Note] NDB: mismatch in frm for panel.gatewayquestions, discovering...090211  9:59:26 [Note] NDB Binlog: DISCOVER TABLE Event: REPL$panel/gatewayquestions090211  9:59:26 [Note] NDB Binlog: logging ./panel/gatewayquestions (UPDATED,USE_WRITE)This is due to the files already being in the mysql data directory. After the error thefrm does not match the data in memory this causes the following.When running select count(*) from tablename;You will get an accurate count.When running select * from table name;You get an error Can't find record in tablename. I have seen it as well at some customers usually with bigger installations and many tables.My current recommendation (work around) is to delete the FRM files associated with the NDB tables in the mysql server data directory before you start the mysql server(s).So this is what i always include in my MySQL server startup scripts (and is included in the Configurator scripts):files=`find $mysql_datadir  -name &quot;*.ndb&quot;`for f in $filesdo    x=`basename $f .ndb`    #make sure we leave out ndb_binlog_index and ndb_schema since they are myisam tables    if [ &quot;$x&quot; == &quot;ndb_binlog_index&quot; ]  || [ &quot;$x&quot; == &quot;ndb_schema&quot; ] ;    then       echo &quot;Ignoring $x&quot;    else       y=`echo $f | sed  -e 's#ndb#frm#'`       rm -rf $f       rm -rf $y    fidone#start the mysqld hereIf I want to restore data I usually:stop the clusterstart the data nodes with --initialstop the mysql servers (make sure they are not started)restore the cluster datastart the mysql servers (clearing out whatever .frm files coming from the ndb tables)</description>
    <content:encoded><![CDATA[There are some bug reports on the auto-discovery protocol in MySQL Cluster.<br />The idea of the auto-discovery protocol is to fetch the .frm files for the NDB tables stored in the data dictionary of the data nodes, and put them in the data directory of the mysql server.<br /><br />However, sometimes (not always, which makes it more difficult to reproduce and hence fix), the auto-discovery seems to make strange things (from this <a href="http://bugs.mysql.com/bug.php?id=42773">bug report</a>):<br /><pre>After shuting down and restoring my cluster I get the following error.<br /><br />090211  9:59:26 [Note] NDB: mismatch in frm for panel.gatewayquestions, discovering...<br />090211  9:59:26 [Note] NDB Binlog: DISCOVER TABLE Event: REPL$panel/gatewayquestions<br />090211  9:59:26 [Note] NDB Binlog: logging ./panel/gatewayquestions (UPDATED,USE_WRITE)<br /><br />This is due to the files already being in the mysql data directory. After the error the<br />frm does not match the data in memory this causes the following.<br />When running select count(*) from tablename;<br />You will get an accurate count.<br />When running select * from table name;<br />You get an error Can't find record in tablename.<br /></pre> I have seen it as well at some customers usually with bigger installations and many tables.<br /><br />My current recommendation (work around) is to delete the FRM files associated with the NDB tables in the mysql server data directory before you start the mysql server(s).<br /><br />So this is what i always include in my MySQL server startup scripts (and is included in the <a href="http://www.severalnines.com/config">Configurator</a> scripts):<br /><pre>files=`find $mysql_datadir  -name "*.ndb"`<br />for f in $files<br />do<br />    x=`basename $f .ndb`<br />    #make sure we leave out ndb_binlog_index and ndb_schema since they are myisam tables<br />    if [ "$x" == "ndb_binlog_index" ]  || [ "$x" == "ndb_schema" ] ;<br />    then<br />       echo "Ignoring $x"<br />    else<br />       y=`echo $f | sed  -e 's#ndb#frm#'`<br />       rm -rf $f<br />       rm -rf $y<br />    fi<br />done<br />#start the mysqld here<br /><code></code></pre>If I want to restore data I usually:<br /><ol><li>stop the cluster</li><li>start the data nodes with --initial<br /></li><li>stop the mysql servers (make sure they are not started)<br /></li><li>restore the cluster data</li><li>start the mysql servers (clearing out whatever .frm files coming from the ndb tables)</li></ol><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/19281624-4755810924004513326?l=johanandersson.blogspot.com" /></div>]]></content:encoded>
    <pubDate>Wed, 01 Jul 2009 09:00:00 +0000</pubDate>
    <dc:creator>Johan Andersson</dc:creator>
    <category>usability</category>
    <category>MySQL CLuster 7.0</category>
  </item>

  <item>
    <title>Differences between Oracle and MySQL</title>
    <guid isPermaLink="false">tag:blogger.com,1999:blog-6480555434853676325.post-1950040198333939918</guid>
    <link>http://feedproxy.google.com/~r/MysqlDba-AnOracleDbasJourney/~3/LE7ekAtZWXc/differences-between-oracle-and-mysql.html</link>
    <description>Some key differences for DBAs between Oracle and MySQL database servers include:Different tools used to manage and monitor database servers.Oracle architecture is process based, MySQL architecture is thread based.Different tools used for backup and recovery.Database specific SQL syntax.Database specific SQL functions.Different syntax for stored routines.  MySQL has no packages.MySQL routines are </description>
    <content:encoded><![CDATA[Some key differences for DBAs between Oracle and MySQL database servers include:Different tools used to manage and monitor database servers.Oracle architecture is process based, MySQL architecture is thread based.Different tools used for backup and recovery.Database specific SQL syntax.Database specific SQL functions.Different syntax