<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-16959946</id><updated>2012-02-02T08:20:40.459+01:00</updated><category term='prompt'/><category term='clustering'/><category term='quota'/><category term='protocol'/><category term='logs'/><category term='shards'/><category term='LCA'/><category term='autocommit'/><category term='community'/><category term='cookbook'/><category term='cartoons'/><category term='proposal'/><category term='regexp'/><category term='poll'/><category term='upgrade'/><category term='baltimore'/><category term='prizes'/><category term='rqg'/><category term='scheduler'/><category term='quick'/><category term='extension'/><category term='oreilly'/><category term='zawodny'/><category term='freebsd'/><category term='ACE'/><category term='stored routines'/><category term='recipes'/><category term='rant'/><category term='patch'/><category term='decoder'/><category term='java'/><category term='talk'/><category term='webinar'/><category term='UDF'/><category term='best practices'/><category term='guest'/><category term='policy'/><category term='rcs'/><category term='Summer of Code'/><category term='australia'/><category term='UK'/><category term='continuent'/><category term='clause'/><category term='view'/><category term='innovation'/><category term='mac'/><category term='fix'/><category term='california'/><category term='microsecond'/><category term='blogging'/><category term='google'/><category term='virtualization'/><category term='cluster'/><category term='sun.5.1'/><category term='search engine'/><category term='status'/><category term='benchmarks'/><category term='normalization'/><category term='lua'/><category term='snapshot'/><category term='leadership'/><category term='petabyte'/><category term='ebook'/><category term='site'/><category term='tasks'/><category term='survey'/><category term='participation'/><category term='plugin'/><category term='sushi'/><category term='builds'/><category term='slave'/><category term='maintenance'/><category term='productivity'/><category term='new york'/><category term='update'/><category term='hack'/><category term='tricks'/><category term='revision'/><category term='speaking'/><category term='relay'/><category term='engine'/><category term='RC'/><category term='opendatabasecamp'/><category term='cube'/><category term='indexing'/><category term='join'/><category term='aldiko'/><category term='sheeri'/><category term='xtrabackup'/><category term='filling'/><category term='crc'/><category term='unix'/><category term='forge'/><category term='replication'/><category term='master'/><category term='calendar'/><category term='installation'/><category term='documentation'/><category term='web'/><category term='storage'/><category term='firebird'/><category term='freedom'/><category term='presentation'/><category term='Quality'/><category term='binary log'/><category term='troubleshooting'/><category term='blunders'/><category term='japs'/><category term='sun'/><category term='mysql.sun'/><category term='performance'/><category term='vim'/><category term='injection'/><category term='review'/><category term='plugin.innodb'/><category term='limit'/><category term='cfp'/><category term='backup'/><category term='acquisition'/><category term='definer'/><category term='xml'/><category term='kaj'/><category term='mysql'/><category term='seven'/><category term='semisynch'/><category term='keynote'/><category term='schema'/><category term='dataset'/><category term='advanced'/><category term='storage engine'/><category term='performance_schema'/><category term='filter'/><category term='vertical'/><category term='uc2010'/><category term='android'/><category term='HA'/><category term='replication.conference'/><category term='intel'/><category term='trepctl'/><category term='mysql-proxy'/><category term='topology'/><category term='release'/><category term='pbxt'/><category term='boston'/><category term='forks'/><category term='froscon'/><category term='restaurant'/><category term='federated'/><category term='map'/><category term='planetmysql'/><category term='pivot'/><category term='test maker'/><category term='benchmark'/><category term='gpl'/><category term='GA'/><category term='acid'/><category term='user group'/><category term='cmake'/><category term='social networking'/><category term='amazon'/><category term='browser'/><category term='script'/><category term='dups'/><category term='singapore'/><category term='workbench'/><category term='sontinuent'/><category term='percona'/><category term='presentations'/><category term='operating system'/><category term='crash'/><category term='cassandra'/><category term='platforms'/><category term='fud'/><category term='php'/><category term='distributions'/><category term='chain'/><category term='2010'/><category term='uc2008'/><category term='monitoring'/><category term='careers'/><category term='award'/><category term='free software'/><category term='Birmingham'/><category term='feature'/><category term='hacks'/><category term='article'/><category term='command line'/><category term='uc2009'/><category term='metadata'/><category term='e-commerce'/><category term='instrumentation'/><category term='subquery'/><category term='postgresql'/><category term='tools'/><category term='books'/><category term='bugs'/><category term='pula'/><category term='production'/><category term='development'/><category term='NRC'/><category term='competition'/><category term='5.1'/><category term='events'/><category term='scaling'/><category term='forum.twitter'/><category term='maria'/><category term='athens'/><category term='spider'/><category term='UKOUG'/><category term='sponsoring'/><category term='nosql'/><category term='germany'/><category term='launchpad'/><category term='new technologies'/><category term='solaris'/><category term='voting'/><category term='extending'/><category term='italian'/><category term='reading'/><category term='table'/><category term='contribution'/><category term='lock'/><category term='delayed'/><category term='synchronization'/><category term='openfest'/><category term='laziness'/><category term='camp'/><category term='wordpress'/><category term='report'/><category term='build'/><category term='innodb'/><category term='open core'/><category term='distinct'/><category term='error'/><category term='ingres'/><category term='sharding'/><category term='falcon'/><category term='campus'/><category term='feeds'/><category term='tour'/><category term='Soc'/><category term='challenge'/><category term='packaging'/><category term='support'/><category term='5.5'/><category term='milestone'/><category term='planet'/><category term='talking'/><category term='perl'/><category term='dump'/><category term='advertising'/><category term='signal'/><category term='detect'/><category term='GNU'/><category term='5.6'/><category term='lisbon'/><category term='binaries'/><category term='downloads'/><category term='leopard'/><category term='shell'/><category term='licensing'/><category term='show profiles'/><category term='mysqldump'/><category term='irc'/><category term='statement'/><category term='london'/><category term='council'/><category term='usability'/><category term='spain.madrid'/><category term='hardware'/><category term='row'/><category term='load data'/><category term='santa clara'/><category term='recovery'/><category term='purge'/><category term='stored procedures'/><category term='circular'/><category term='sqlite'/><category term='dba'/><category term='remote'/><category term='mac os x'/><category term='meeting'/><category term='quiz'/><category term='tip'/><category term='stuttgart'/><category term='drizzle'/><category term='multi-master'/><category term='wireless'/><category term='5.4'/><category term='kernel'/><category term='server'/><category term='gcc'/><category term='information_schema'/><category term='university'/><category term='install'/><category term='linas virbalas'/><category term='beer'/><category term='meetup'/><category term='astronomy'/><category term='SQL'/><category term='iterm'/><category term='snow leopard'/><category term='mariadb'/><category term='functions'/><category term='fosdem'/><category term='open source'/><category term='insert'/><category term='db2'/><category term='shortcut'/><category term='bazaar'/><category term='home'/><category term='firefox'/><category term='EOL'/><category term='travel'/><category term='greece'/><category term='tips'/><category term='sql_mode'/><category term='librarian'/><category term='codebits'/><category term='conflict prevention'/><category term='laptop'/><category term='swedish'/><category term='multiple'/><category term='opensqlcamp'/><category term='orlando'/><category term='business'/><category term='scalability'/><category term='san francisco'/><category term='slow'/><category term='security'/><category term='contributions'/><category term='cloud'/><category term='hacker'/><category term='oracle'/><category term='hiring'/><category term='europe'/><category term='session'/><category term='coding'/><category term='fun'/><category term='integrity'/><category term='testing'/><category term='sandbox'/><category term='jan'/><category term='myth'/><category term='sardinia'/><category term='proxy'/><category term='admin'/><category term='bbq'/><category term='apple'/><category term='partitions'/><category term='ipad'/><category term='IOUG'/><category term='conference'/><category term='partitioning'/><category term='cagliari'/><category term='feedback'/><category term='transactions'/><category term='python'/><category term='tungsten'/><category term='crosstab'/><category term='parallel'/><category term='database'/><category term='linux'/><category term='primary key'/><category term='sun.madrid'/><category term='oscon'/><category term='records'/><category term='programming'/><category term='tutorial'/><category term='trigger'/><category term='mongodb'/><category term='book'/><category term='options'/><category term='conflict'/><category term='RBR'/><category term='jobs'/><category term='terminal'/><category term='world tour'/><category term='gearman'/><category term='qa'/><category term='languages'/><category term='3.0'/><category term='drupal'/><category term='tagging'/><category term='mixed'/><title type='text'>The Data Charmer</title><subtitle type='html'>Data seem sometimes to have their own life and will, and they refuse to behave as we wish. &lt;br&gt;
Then, you need a firm hand to tame the wild data and turn them into quiet and obeying pets.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default?start-index=101&amp;max-results=100'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>428</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-16959946.post-1028914944024333082</id><published>2012-01-27T20:32:00.001+01:00</published><updated>2012-01-27T20:34:11.526+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='ACE'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>More Oracle ACEs for MySQL</title><content type='html'>&lt;a href="http://apex.oracle.com/pls/otn/f?p=19297:3:312346392932782:::::"&gt;&lt;img src="http://lh3.ggpht.com/-CtYLt4dJRus/TyL7rppyUxI/AAAAAAAABPg/IKJgkX19tGQ/Screen%252520Shot%2525202012-01-27%252520at%25252019.49.18%252520.png?imgmax=800" alt="Oracle ACEs for MySQL" title="Oracle ACEs for MySQL" border="0" width="600" height="513" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;As Keith &lt;a href="http://sqlhjalp.blogspot.com/2012/01/well-deserved.html"&gt;announced today&lt;/a&gt;, there are two more Oracle ACE Directors for MySQL expertise.  In case you are wondering how an ACE Director compares to a regular ACE, here is an &lt;a href="http://www.oracle.com/technetwork/community/index-083638.html"&gt;overview&lt;/a&gt; and &lt;a href="http://www.oracle.com/technetwork/community/oracle-ace-faq-100746.html#7"&gt;some FAQ&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1028914944024333082?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1028914944024333082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1028914944024333082' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1028914944024333082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1028914944024333082'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2012/01/more-oracle-aces-for-mysql.html' title='More Oracle ACEs for MySQL'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-CtYLt4dJRus/TyL7rppyUxI/AAAAAAAABPg/IKJgkX19tGQ/s72-c/Screen%252520Shot%2525202012-01-27%252520at%25252019.49.18%252520.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1050881713830325880</id><published>2012-01-18T16:46:00.001+01:00</published><updated>2012-01-27T12:35:14.922+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='fosdem'/><category scheme='http://www.blogger.com/atom/ns#' term='events'/><title type='text'>MySQL and Friends schedule at FOSDEM 2012</title><content type='html'>&lt;a href="http://www.fosdem.org"&gt;&lt;img src="http://www.fosdem.org/promo/badge/fosdem12-blue.png" alt="FOSDEM, the Free and Open Source Software Developers' European Meeting" /&gt;&lt;/a&gt; The MySQL DevRoom at &lt;a href="http://fosdem.org"&gt;FOSDEM&lt;/a&gt; is ready. The schedule has been voted. Thanks to all who have participated.  Now, let's make sure that the event is successful. The &lt;a href="http://fosdem.org/2012/schedule/track/mysql_and_friends_devroom"&gt;schedule&lt;/a&gt; is juicy, and not only because I have three talks in it!       &lt;table &gt;&lt;tbody&gt;&lt;tr &gt;           &lt;td colspan="4"&gt;           &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td  colspan="4"&gt;Sunday 2012-02-05&lt;/td&gt;&lt;tr&gt;             &lt;th &gt;Event&lt;/th&gt;             &lt;th &gt;Speaker&lt;/th&gt;             &lt;th &gt;Room&lt;/th&gt;             &lt;th &gt;When&lt;/th&gt;           &lt;/tr&gt;&lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/all_you_need_to_know_about_migrations"&gt;All you need to know about migrations and you never dared to ask&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/ralf_gebhardt_"&gt;Ralf Gebhardt &lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 09:05-09:30          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/sphinx_user_stories"&gt;Sphinx User stories&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/stephane_varoqui_"&gt;St&amp;#233;phane Varoqui &lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 09:35-10:00          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/mysql_ha_reloaded"&gt;MySQL HA reloaded - old tricks and cool new tools to guarantee high availability to your MySQL Servers&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/ivan_zoratti"&gt;Ivan Zoratti&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 10:00-10:25          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/mariadb_optimizer"&gt;MariaDB 5.3's query optimizer: taking the dolphin to where he's never been before&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/sergey_petrunya"&gt;Sergey Petrunya&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 10:30-10:55          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/offload_mysql_with_sphinx"&gt;How to offload MySQL server with Sphinx&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/vladimir_fedorkov"&gt;Vladimir Fedorkov&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 11:00-11:25          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;b&gt;** &lt;a href="http://fosdem.org/2012/schedule/event/replication_cluster_with_tungsten"&gt;Build simple and complex replication clusters with Tungsten Replicator&lt;/a&gt;&lt;/b&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/giuseppe_maxia"&gt;Giuseppe Maxia&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;&lt;b&gt; 11:30-11:55         &lt;/b&gt; &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/cluster_internals"&gt;Cluster internals&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/ralf_gebhardt_"&gt;Ralf Gebhardt &lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 12:00-12:25          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/optimising_sql_applications_using_client_side_tools"&gt;Optimising SQL applications by using client side tools&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/mark_riddoch"&gt;Mark Riddoch&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 12:30-12:55          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             ** &lt;a href="http://fosdem.org/2012/schedule/event/mysql_replication_101"&gt;&lt;strike&gt;MySQL Replication 101 &lt;/strike&gt;&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/giuseppe_maxia"&gt;Giuseppe Maxia&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td&gt; 13:00-13:25         &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/choosing_hw_for_mysql"&gt;Choosing Hardware for MySQL&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/kenny_gryp"&gt;Kenny Gryp&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 13:30-13:55          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/replication_2011"&gt;Replication features of 2011: what they were, how to get and how to use them&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/sergey_petrunya"&gt;Sergey Petrunya&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 14:00-14:25          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;b&gt;** &lt;a href="http://fosdem.org/2012/schedule/event/mysql_creatively_in_a_sandbox"&gt;MySQL creatively in a sandbox&lt;/a&gt;&lt;/b&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/giuseppe_maxia"&gt;Giuseppe Maxia&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;&lt;b&gt; 14:30-14:55          &lt;/b&gt;&lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/mysql_la_poste"&gt;Case Study: La Poste - Real Time, High Volume Data Warehousing Using MySQL &amp;amp; InfiniDB&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/stephane_varoqui_"&gt;St&amp;#233;phane Varoqui &lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 15:00-15:25          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/sphinx_perf_top_secret"&gt;Sphinx performance top secret&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/vladimir_fedorkov"&gt;Vladimir Fedorkov&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 15:30-15:55          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/percona_toolkit"&gt;Managing MySQL with Percona Toolkit&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/frederic_descamps"&gt;Fr&amp;#233;d&amp;#233;ric Descamps&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 16:00-16:25          &lt;/td&gt;         &lt;/tr&gt;&lt;tr &gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/event/dw_with_mysql"&gt;Data Warehousing with MySQL&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/speaker/ivan_zoratti"&gt;Ivan Zoratti&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt;             &lt;a href="http://fosdem.org/2012/schedule/room/h1309"&gt;H.1309&lt;/a&gt;           &lt;/td&gt;           &lt;td &gt; 16:30-16:55          &lt;/td&gt;         &lt;/tr&gt;&lt;/tbody&gt;     &lt;/table&gt;&lt;br /&gt;&lt;b&gt;UPDATE&lt;/b&gt; The &lt;a href="http://fosdem.org/2012/schedule/track/mysql_and_friends_devroom"&gt;schedule&lt;/a&gt; has changed. Speakers with more than one talk have been asked to give up one. Now I have two talks instead of three.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1050881713830325880?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1050881713830325880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1050881713830325880' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1050881713830325880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1050881713830325880'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2012/01/mysql-and-friends-schedule-at-fosdem.html' title='MySQL and Friends schedule at FOSDEM 2012'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-7546550123952214666</id><published>2012-01-02T23:16:00.001+01:00</published><updated>2012-01-02T23:22:34.391+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='presentations'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='opensqlcamp'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='participation'/><category scheme='http://www.blogger.com/atom/ns#' term='fosdem'/><category scheme='http://www.blogger.com/atom/ns#' term='free software'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Time to vote for MySQL sessions at FOSDEM</title><content type='html'>&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://fosdem.org"&gt;&lt;img src="http://lh4.ggpht.com/-Mf0GDNbozEI/TwIsza6k4AI/AAAAAAAABPI/IaSovPe6l7A/fosdem_2012_info.png?imgmax=800" alt="Fosdem 2012 info" title="fosdem_2012_info.png" border="0" width="300"  /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;There is a room dedicated to MySQL at &lt;a href="http://fosdem.org"&gt;FOSDEM 2012&lt;/a&gt;. (Thanks to &lt;a href="https://twitter.com/#!/lefred"&gt;@lefred&lt;/a&gt; for organizing).The CfP has received 37 submissions, but there will be time slots only for 12 to 15 talks. So now it's up to the community. If you want to attend a particular talk, you should vote for it.Like in previous years, the selection of the talks is public. You can see the &lt;a href="http://code.google.com/p/mysql-forge/wiki/FOSDEM_2012_MySQL_and_Friends_proposals"&gt;list of the proposals&lt;/a&gt;, with the instructions, which I repeat here.You can vote either publicly, using Twitter, or privately, by sending an email. Each talk proposal will be referred by the number immediately after the title in this page. This number indicates the order in which the proposals were received. In public, you should send a tweet to &lt;a href="https://twitter.com/#!/opensqlcamp"&gt;@opensqlcamp&lt;/a&gt;, indicating a maximum of 12 talks that you would like to see, in the order you like them. e.g. &lt;code&gt;"@opensqlcamp #FOSDEM2012 1,2,3,4,5,6,7,8,9,10,11,12 http://bit.ly/mysql_fosdem_2012"&lt;/code&gt; (adding the link will help others to find the page.In private, by email at &lt;b&gt;mysqlfriends AT gmail DOT com&lt;/b&gt;, using the same method used for Twitter. Maximum 12 talks, in the order of your preference.In both cases, votes for your preferences will result in 1 point for each talk. In case of equal voting, we will assign 12 points to the first in the list, 11 to the second, and so on. We'll do the tally, and choose the most popular ones.Anonymous votes either by Twitter or email won't be counted. If you want your vote to count, make sure your twitter account has a recognized name (or known nick) on it. If your email address doesn't spell your name, please sign the message with your real one.DEADLINE: Your votes must be entered &lt;b&gt;by January 8th, 2011&lt;/b&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-7546550123952214666?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/7546550123952214666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=7546550123952214666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7546550123952214666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7546550123952214666'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2012/01/time-to-vote-for-mysql-sessions-at.html' title='Time to vote for MySQL sessions at FOSDEM'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-Mf0GDNbozEI/TwIsza6k4AI/AAAAAAAABPI/IaSovPe6l7A/s72-c/fosdem_2012_info.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-6231639687718385832</id><published>2011-12-19T15:53:00.001+01:00</published><updated>2011-12-19T16:10:11.252+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='percona'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='upgrade'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='mariadb'/><category scheme='http://www.blogger.com/atom/ns#' term='recipes'/><title type='text'>Testing new builds with MySQL-Sandbox 3.0.24</title><content type='html'>&lt;a href="http://mysqlsandbox.net"&gt;MySQL::Sandbox&lt;/a&gt; 3.0.24 was released yesterday, with many &lt;a href="http://mysqlsandbox.net/news.html"&gt;new features&lt;/a&gt;.  &lt;h3&gt;More than vanilla MySQL&lt;/h3&gt;If you have missed my previous announcement, here's the gist of it. MySQL Sandbox can now deal with tarballs from either &lt;a href="http://www.percona.com/software/percona-server/"&gt;Percona Server&lt;/a&gt; or &lt;a href="http://downloads.askmonty.org/mariadb/"&gt;MariaDB&lt;/a&gt;.  The main difference after this change is that you can now create a directory called &amp;lt;PREFIX&amp;gt;5.5.16 and make_sandbox will recognize it as well as the plain 5.5.16.   &lt;pre&gt;$ &lt;b&gt;make_sandbox --export_binaries --add_prefix=ps \&lt;br /&gt;   Percona-Server-5.5.11-rel20.2-114.Darwin.i386.tar.gz  \&lt;br /&gt;   -- --sandbox_directory=msb_ps5_5_11&lt;/b&gt;&lt;br /&gt;unpacking Percona-Server-5.5.11-rel20.2-114.Darwin.i386.tar.gz&lt;br /&gt;[…]&lt;br /&gt;installing with the following parameters:&lt;br /&gt;upper_directory                = /Users/gmax/sandboxes&lt;br /&gt;sandbox_directory              = msb_ps5_5_11&lt;br /&gt;[…]&lt;br /&gt;basedir                        = $HOME/opt/mysql/ps5.5.11&lt;br /&gt;tmpdir                         = &lt;br /&gt;[…]&lt;br /&gt;Your sandbox server was installed in $HOME/sandboxes/msb_ps5_5_11&lt;br /&gt;&lt;/pre&gt;After the binary export, subsequent installations will be easier:  &lt;pre&gt;$ &lt;b&gt;make_sandbox ps5.5.11&lt;/b&gt;&lt;br /&gt;&lt;/pre&gt;The same commands can be used for MariaDB. At the moment, make_sandbox does not recognize other packages, but adding them should not be a big deal, provided that such packages look like MySQL. It wouldn't work with Drizzle, because it lacks the main ingredients for MySQL installation.  &lt;h3&gt;High Performance sandboxes&lt;/h3&gt;While testing parallel replication and prefetch slaves with &lt;a href="http://tungsten-replicator.org"&gt;Tungsten Replicator&lt;/a&gt;, I realized that I was doing too much manual fiddling with my scripts. Since I need more performant servers, I added the basic items that I need to modify to enable a faster server. Now, using the '--high_performance' option with make_sandbox, you get a server that is much better than out-of-the-box MySQL. To avoid problems with too much RAM, I am using a default of 512 MB for InnoDB, which is not enough for really demanding tests, but at least it is a good placeholder in the sandbox configuration file, should you need to modify it.  &lt;pre&gt;$ &lt;b&gt;make_sandbox 5.1.60 -- --high_performance&lt;/b&gt;&lt;br /&gt;[…]&lt;br /&gt;innodb-flush-method=O_DIRECT ; \&lt;br /&gt;innodb-log-file-size=50M ; \&lt;br /&gt;innodb_buffer_pool_size=512M ; \&lt;br /&gt;max_allowed_packet=48M ; \&lt;br /&gt;max-connections=350 ; \&lt;br /&gt;innodb-additional-mem-pool-size=50M ; \&lt;br /&gt;innodb-log-buffer-size=50M ; sync_binlog=0 ; \&lt;br /&gt;innodb-thread-concurrency=0 ; log-error=msandbox.err&lt;br /&gt;[…]&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Standalone masters and slaves&lt;/h3&gt;MySQL Sandbox has had the ability of creating replicated systems for years. Yet, sometimes you need a stand-alone master server that you want to use for some odd experiment. Similarly, you may want to create a slave of a specific master without having a full replication system.  One case where you would like this ability is when you want to try &lt;b&gt;replicating between servers of different versions&lt;/b&gt;.   &lt;pre&gt;$ &lt;b&gt;make_sandbox 5.1.57 -- --master&lt;/b&gt;&lt;br /&gt;[…]&lt;br /&gt;my_clause                      = server-id=5157 ; log-bin=mysql-bin ; log-error=msandbox.err&lt;br /&gt;[…]&lt;br /&gt;Your sandbox server was installed in $HOME/sandboxes/msb_5_1_57&lt;br /&gt;&lt;br /&gt;$ &lt;b&gt;make_sandbox 5.5.10 -- --slaveof='master_port=5157' &lt;/b&gt;&lt;br /&gt;[…]&lt;br /&gt;my_clause                      = server-id=5510 ; log-bin=mysql-bin ; log-error=msandbox.err&lt;br /&gt;[…]&lt;br /&gt;Your sandbox server was installed in $HOME/sandboxes/msb_5_5_10&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$ &lt;b&gt;~/sandboxes/msb_5_1_57/use -e 'show master status'&lt;/b&gt;&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;| mysql-bin.000001 |      106 |              |                  |&lt;br /&gt;+------------------+----------+--------------+------------------+&lt;br /&gt;&lt;br /&gt;$ &lt;b&gt;~/sandboxes/msb_5_5_10/use -e 'show slave status\G'&lt;/b&gt;&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;               Slave_IO_State: Waiting for master to send event&lt;br /&gt;                  Master_Host: 127.0.0.1&lt;br /&gt;                  Master_User: rsandbox&lt;br /&gt;                  Master_Port: 5157&lt;br /&gt;                Connect_Retry: 60&lt;br /&gt;              Master_Log_File: mysql-bin.000001&lt;br /&gt;          Read_Master_Log_Pos: 106&lt;br /&gt;               Relay_Log_File: mysql_sandbox5510-relay-bin.000002&lt;br /&gt;                Relay_Log_Pos: 252&lt;br /&gt;        Relay_Master_Log_File: mysql-bin.000001&lt;br /&gt;             Slave_IO_Running: Yes&lt;br /&gt;            Slave_SQL_Running: Yes&lt;br /&gt;              Replicate_Do_DB: &lt;br /&gt;          Replicate_Ignore_DB: &lt;br /&gt;           Replicate_Do_Table: &lt;br /&gt;       Replicate_Ignore_Table: &lt;br /&gt;      Replicate_Wild_Do_Table: &lt;br /&gt;  Replicate_Wild_Ignore_Table: &lt;br /&gt;                   Last_Errno: 0&lt;br /&gt;                   Last_Error: &lt;br /&gt;                 Skip_Counter: 0&lt;br /&gt;          Exec_Master_Log_Pos: 106&lt;br /&gt;              Relay_Log_Space: 420&lt;br /&gt;              Until_Condition: None&lt;br /&gt;               Until_Log_File: &lt;br /&gt;                Until_Log_Pos: 0&lt;br /&gt;           Master_SSL_Allowed: No&lt;br /&gt;           Master_SSL_CA_File: &lt;br /&gt;           Master_SSL_CA_Path: &lt;br /&gt;              Master_SSL_Cert: &lt;br /&gt;            Master_SSL_Cipher: &lt;br /&gt;               Master_SSL_Key: &lt;br /&gt;        Seconds_Behind_Master: 0&lt;br /&gt;Master_SSL_Verify_Server_Cert: No&lt;br /&gt;                Last_IO_Errno: 0&lt;br /&gt;                Last_IO_Error: &lt;br /&gt;               Last_SQL_Errno: 0&lt;br /&gt;               Last_SQL_Error: &lt;br /&gt;  Replicate_Ignore_Server_Ids: &lt;br /&gt;             Master_Server_Id: 5157&lt;br /&gt;&lt;/pre&gt;You can download MySQL::Sandbox from either &lt;a href="http://launchpad.net/mysql-sandbox/+download"&gt;launchpad&lt;/a&gt; or &lt;a href="http://search.cpan.org/perldoc?MySQL::Sandbox"&gt;CPAN&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-6231639687718385832?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/6231639687718385832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=6231639687718385832' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6231639687718385832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6231639687718385832'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/12/testing-new-builds-with-mysql-sandbox.html' title='Testing new builds with MySQL-Sandbox 3.0.24'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-3106136869470004468</id><published>2011-12-10T22:17:00.001+01:00</published><updated>2011-12-10T22:47:15.899+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>How to submit a good database bug report</title><content type='html'>When an open source project becomes popular, bug reports start flocking in. This is both good and bad news for the project developers.  The good news is that someone is using the product, and they are finding ways of breaking it that we didn't think of. The bad news is that most of the times the reporters assume that the developers have super human powers, and that they will find what's wrong by the simple mentioning that a given feature is not working as expected. Unfortunately, it doesn't work that way. An effective bug report should have enough information that the ones in charge will be able to reproduce it and examine in lab conditions to find the problem. When dealing with databases and database tools, there are several cases, from simple to complex. Let's cover them in order.  &lt;h3&gt;Installation issues&lt;/h3&gt;This is often a straightforward case of lack of functionality. When a tool does not install what it is supposed to, it is a show stopper, and a solution must be found. In this case, it's often enough to state the environment where the installation is happening (operating system, version of the tool, version of core components such as the MySQL database used) and the command used to start the installation. The error message could be an expected failure, when the installation procedure checks for requirements and fails if they are not met. For example: "Missing Ruby interpreter". The message tells (or suggests) you what to do. Filing a bug report on an expected failure is a waste of time. You should install the missing part and try again. Even if the message is about an unexpected failure (e.g. you get a stack trace from Ruby or Java), usually the first message tells you enough to be able to find a workaround. For example, if you get an exception from Ruby complaining about a missing 'curl' command, you can file a bug report to ask for the installer to check for 'curl' in the requirements, but if you install 'curl' yourself, the installation should continue.  &lt;h3&gt;Simple database issues&lt;/h3&gt;Reporting a database bug means complaining that the DBMS is not behaving as advertising by the documentation, or as common usage dictates. If it is a missing or misbehaving functionality, the best way of showing the problem is by starting with an empty DBMS, followed by the creation of the objects needed to reproduce the issue (CREATE SCHEMA, TABLE, INDEX) and by a minimal amount of data that triggers the problem.  Some information about what operating system and database version was used is probably necessary to reproduce the problem consistently.  &lt;h3&gt;Simple database replication issues&lt;/h3&gt;By &lt;i&gt;simple replication&lt;/i&gt; we mean a vanilla master/slave topology. In this scheme, data inserted in the master will eventually end up in the slave. Bugs in this category may fail to replicate the data totally or partially, or they may cause a break in the replication flow. Reproducing them is almost as easy as with simple database bugs. If you start with an empty system and manage to reproduce the error with a short sequence of commands, it should probably reproducible by a third party. Sometimes, settings in the master and the slave are essential to reproduce the problem. In MySQL, the format of binary logs, the default database engine and SQL modes can affect replication and produce different results with the same stream of SQL commands.  &lt;h3&gt;Complex database replication issues&lt;/h3&gt;The most difficult bugs to report are the ones where the error shows up only in a given topology. While MySQL native replication offers only few options to pipe data around (single, circular, hierarchical), Tungsten replicator allows a rich set of combined pipelines that can change the outcome of a data change event, depending on the originating node and the direction it took. In these case, information o how the cluster was installed becomes essential.   &lt;h3&gt;Concurrency issues&lt;/h3&gt;This is one of the most difficult bugs to report. When an error happens only because of the contemporary action of two or more threads, there is no easy way of reporting it in a way that it can be easily reproduced. Three methods are possible: &lt;ul&gt;&lt;li&gt;Describe the action of the first thread, then mark the change of thread and describe the actions of the second thread, continuing in this way until you reach the error point.&lt;/li&gt;&lt;li&gt;If you are a developer and feel comfortable with multi thread applications, write a script that reproduces the error by running several threads (Perl, Python, and Ruby offer the best environment for this kind of tests).&lt;/li&gt;&lt;li&gt;If the database offers a tool to write such multi-threading tests, consider using it.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Heavy load issues&lt;/h3&gt;This is a more complex case of the above one. Not only you need concurrency, but a lot of it happening at the same time. Reproducing this kind or error is challenging. If you have a support agreement with the provider of the database or the tool, you may let the support engineer have a look at your running environment, to find some clues. But even in this case, the support engineers or yourself need to ultimately reproduce the case in such a way that a developer can fix the problem and test the fix. There are two methods to report this problem: &lt;ul&gt;&lt;li&gt;Simplification: if you can reduce the concurrency to the elements that are misbehaving, the methods for concurrency issues will apply also in this case.&lt;/li&gt;&lt;li&gt;Enabling a query log could lead to identifying the sequence of events that have generated the error. The log should be integrated by the DDL of the objects involved in the action (schemas, tables, triggers, views, etc).&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Large data issues&lt;/h3&gt;If your error only shows itself with large data, there is often a logistical problem, as you can't easily provide gigabytes of data, even if there privacy and security issues weren't in the way (which usually are). There are three strategies that you can use to report such bugs: &lt;ul&gt;&lt;li&gt;If only the size matters, then describing the kind of data used could be enough. E.g. &lt;i&gt;When a table with such fields and such indexes grows beyond X GB, then the optimizer warp drive explodes.&lt;/i&gt; (Don't try this at home)&lt;/li&gt;&lt;li&gt;Create a script to generate the data that will ultimately trigger the error. This method requires both skills and an understanding of what the error is.&lt;/li&gt;&lt;li&gt;You may use a publicly available database to reproduce the error (for example, the &lt;a href="https://launchpad.net/test-db"&gt;Sample database with test suite&lt;/a&gt;.) Just mention in the bug report where to find the database, eventually how to load it if it is not simple, and then describe the steps needed to reproduce the bug after loading it.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;DOs and DONTs&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;DO  &lt;ul&gt;&lt;li&gt;Search the bug repository and the mailing lists (or forums) before submitting yours. Someone may have had the same problem before you did. (Thanks, Robert Hodges, for this important reminder.)&lt;/li&gt;&lt;li&gt;Put yourself in the receiver's position, and try to reproduce the problem from a clean initial state.&lt;/li&gt;&lt;li&gt;If there is a workaround, mention it: it might give a good clue to the developers.&lt;/li&gt;&lt;li&gt;More information is better. Anything that can improve the identification of the bug root cause will be welcome. (But don't overdo: see below)&lt;/li&gt;&lt;li&gt;If you feel that a missing feature should be useful, report it as a feature request. (Even better: suggest a patch)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;DON'T  &lt;ul&gt;&lt;li&gt;Don't report a missing feature as a bug, unless the docs say that the feature should be there.&lt;/li&gt;&lt;li&gt;Don't just send the error message without the events that generated it.&lt;/li&gt;&lt;li&gt;Don't include SQL commands embedded in code.&lt;/li&gt;&lt;li&gt;Don't say "my application doesn't work anymore," assuming it's the database's fault. Remember &lt;a href="http://www.codinghorror.com/blog/2008/03/the-first-rule-of-programming-its-always-your-fault.html"&gt;The First Rule of Programming: It's Always Your Fault&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Less is better. If there is a long way and a short way of reproducing the bug, the shorter one is better. Don't send more info just for the sake of it.&lt;/li&gt;&lt;li&gt;Don't tell the developers that they are retarded. This will not increase the priority given to your bug, or your credibility.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-3106136869470004468?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/3106136869470004468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=3106136869470004468' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3106136869470004468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3106136869470004468'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/12/how-to-submit-good-database-bug-report.html' title='How to submit a good database bug report'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-4593761017420624568</id><published>2011-12-02T13:00:00.000+01:00</published><updated>2011-12-02T13:00:13.408+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='santa clara'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='europe'/><category scheme='http://www.blogger.com/atom/ns#' term='percona'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='california'/><category scheme='http://www.blogger.com/atom/ns#' term='fosdem'/><title type='text'>Call for participation for MySQL events - MySQL conference and FOSDEM</title><content type='html'>It's that time of the year where MySQL would be speakers are called to action. As usual, the main event is the MySQL spring conference, this year hosted by &lt;a href="http://www.percona.com"&gt;Percona&lt;/a&gt;. The call for participation to the &lt;a href="http://www.percona.com/live/mysql-conference-2012/"&gt;MySQL Conference And Expo 2012&lt;/a&gt; is still open until December 5th. To submit a proposal, you should register as a speaker and then fill in the &lt;a href="http://www.percona.com/live/mysql-conference-2012/node/add/session"&gt;form&lt;/a&gt;.&lt;br /&gt;There is a &lt;a href="http://www.percona.com/live/mysql-conference-2012/conference-committee"&gt;conference committee&lt;/a&gt; which is already busy evaluating the proposals that have been submitted so far. The committee is demanding (I know for a fact, since I am in it!) and therefore, if you want to submit something, be very critical with yourself and polish your proposal as if your job depended on it!&lt;br /&gt;Please read &lt;a href="http://www.mysqlperformanceblog.com/2011/11/30/an-update-on-percona-live-mysql-conference-expo-2012/"&gt;an update on Percona Live MySQL Conference &amp; Expo 2012&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Speakers in Europe have some more duty, though. This is also the time to submit talks for &lt;a href="http://fosdem.org"&gt;FOSDEM&lt;/a&gt; MySQL DevRoom. Thanks to Fr&amp;eacute;d&amp;eacute;ric Descamps and Sergey Petrunia, we have Room H.1309 with 150 seats on Sunday 5th February 2012, all day. The deadline to submit a talk proposal is December 26th. There is no review committee. Like we did on past editions, as soon as the talks are submitted, we will ask everyone to vote on the talks via Twitter or email. More updates will come soon. Of course, participation to FOSDEM DevRoom is not limited to European speakers. There have been several brave speakers who have willingly crossed the pond to offer their services at European conferences before, and they are welcome to repeat the experience. &lt;a href="https://docs.google.com/spreadsheet/viewform?formkey=dFFBSGdEc2pRU1E4N1NoRlNhR1BFQkE6MQ"&gt;Submit your talk proposals&lt;/a&gt; now.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-4593761017420624568?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/4593761017420624568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=4593761017420624568' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4593761017420624568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4593761017420624568'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/12/call-for-participation-for-mysql-events.html' title='Call for participation for MySQL events - MySQL conference and FOSDEM'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-3098605928338576278</id><published>2011-12-01T08:00:00.001+01:00</published><updated>2011-12-01T14:33:44.329+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tricks'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><title type='text'>Never say "there is no way"</title><content type='html'>Reading a recent MySQL book, I saw an example of SHOW CREATE TABLE that comes with backticks (`) around the table and column names, and a comment:&lt;br /&gt;&lt;blockquote&gt;Unfortunately, &lt;i&gt;there is no way&lt;/i&gt; to remove this from generated syntax with this command.&lt;/blockquote&gt;(Emphasis mine).&lt;br /&gt;Here's how it goes:&lt;br /&gt;&lt;pre&gt;mysql&amp;gt; show create table mytest\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;       Table: mytest&lt;br /&gt;Create Table: CREATE TABLE `mytest` (&lt;br /&gt;  `id` int(11) NOT NULL,&lt;br /&gt;  `description` varchar(50) DEFAULT NULL,&lt;br /&gt;  PRIMARY KEY (`id`)&lt;br /&gt;) ENGINE=InnoDB DEFAULT CHARSET=latin1&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;Of course, there is a way!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;mysql&amp;gt; &lt;b&gt;pager tr -d '`'&lt;/b&gt;&lt;br /&gt;PAGER set to 'tr -d '`''&lt;br /&gt;mysql&amp;gt; show create table mytest\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;       Table: mytest&lt;br /&gt;Create Table: CREATE TABLE mytest (&lt;br /&gt;  id int(11) NOT NULL,&lt;br /&gt;  description varchar(50) DEFAULT NULL,&lt;br /&gt;  PRIMARY KEY (id)&lt;br /&gt;) ENGINE=InnoDB DEFAULT CHARSET=latin1&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;Never say "there is no way!"&lt;br /&gt;&lt;br /&gt;Instead of "tr -d '`'", you can use "sed -e 's/`//g'", which does the same thing.&lt;br /&gt;&lt;br /&gt;If you are running the query at the command line, you may use the pipe directly:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ mysql -e 'show create table test.mytest\G' | tr -d '`'&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;       Table: mytest&lt;br /&gt;Create Table: CREATE TABLE mytest (&lt;br /&gt;  id int(11) NOT NULL,&lt;br /&gt;  description varchar(50) DEFAULT NULL,&lt;br /&gt;  PRIMARY KEY (id)&lt;br /&gt;) ENGINE=InnoDB DEFAULT CHARSET=latin1&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-3098605928338576278?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/3098605928338576278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=3098605928338576278' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3098605928338576278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3098605928338576278'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/12/never-say-there-is-no-way.html' title='Never say &quot;there is no way&quot;'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-651168652658416419</id><published>2011-11-04T16:58:00.000+01:00</published><updated>2011-11-04T17:08:20.232+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='best practices'/><category scheme='http://www.blogger.com/atom/ns#' term='multiple'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><category scheme='http://www.blogger.com/atom/ns#' term='HA'/><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='master'/><category scheme='http://www.blogger.com/atom/ns#' term='challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='multi-master'/><category scheme='http://www.blogger.com/atom/ns#' term='conflict prevention'/><category scheme='http://www.blogger.com/atom/ns#' term='innovation'/><category scheme='http://www.blogger.com/atom/ns#' term='conflict'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Replication stars</title><content type='html'>Working with replication, you come across many topologies, some of them sound and established, some of them less so, and some of them still in the realm of the hopeless wishes. I have been working with replication for almost 10 years now, and my wish list grew quite big during this time. In the last 12 months, though, while working at Continuent, some of the topologies that I wanted to work with have moved from the cloud of wishful thinking to the firm land of things that happen.  My quest for star replication starts with the most common topology. One master, many slaves. &lt;table border="0""&gt;&lt;tr&gt;&lt;td&gt; &lt;img src="http://lh6.ggpht.com/-ZdubvXSXpyI/TrPFPlH8WJI/AAAAAAAABNw/ndLQKrtpCms/replication_1_master_slave.png?imgmax=800" alt="Replication 1 master slave" title="master slave" border="0" width="257" height="219"/&gt; &lt;p align="center"&gt;&lt;i&gt;Fig 1. Master/Slave topology&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt; &lt;img src="http://lh6.ggpht.com/-xnqiEpTqtgw/TrPFYQfZ-vI/AAAAAAAABOw/NlJOp9ob3bw/replication_legend.png?imgmax=800" alt="Replication legend" title="replication_legend.png" border="0" width="184" height="163" /&gt; &lt;p align="center"&gt;&lt;i&gt;Legend&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;It looks like a star, with the rays extending from the master to the slaves. This is the basis of most of the replication going on mostly everywhere nowadays, and it has few surprises. Setting aside the problems related to failing over and switching between nodes, which I will examine in another post, let's move to another star.  &lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt; &lt;img src="http://lh5.ggpht.com/-brhLZb3Io7Y/TrPFQuS791I/AAAAAAAABN4/QCglBzIn9gc/replication_2_fan_in_slave.png?imgmax=800" alt="Replication 2 fan in slave" title="fan-in slave" border="0" width="249" height="207" /&gt; &lt;p align="center"&gt;&lt;i&gt;Fig 2. Fan-in slave, or multiple sources&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;The &lt;i&gt;multiple source replication&lt;/i&gt;, also known as &lt;i&gt;fan-in&lt;/i&gt; topology, has several masters that replicate to the same slave. For years, this has been forbidden territory for me. But &lt;a href="http://tungsten-replicator.org"&gt;Tungsten Replicator&lt;/a&gt; allows you to &lt;a href="http://datacharmer.blogspot.com/2011/08/usability-improvements-in-tungsten-204.html"&gt;create multiple source topologies easily&lt;/a&gt;. This is kind of uni-directional, though. I am also interested in topologies where I have more than one master, and I can retrieve data from multiple points.  &lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt; &lt;img src="http://lh4.ggpht.com/-0G1Zum3dA5M/TrPFRpamPaI/AAAAAAAABOA/RsKItTUdB5U/replication_3_all_to_all_three_nodes.png?imgmax=800" alt="Replication 3 all to all three nodes" title="all to all three nodes" border="0" width="240" height="186" /&gt; &lt;p align="center"&gt;&lt;i&gt;Fig 3. all-to-all three nodes&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt; &lt;img src="http://lh3.ggpht.com/-NLK6ERpxbmM/TrPFSuahrdI/AAAAAAAABOI/MzI6_cH4e2U/replication_4_all_to_all_four_nodes.png?imgmax=800" alt="Replication 4 all to all four nodes" title="all to all four nodes" border="0" width="295" height="239" /&gt; &lt;p align="center"&gt;&lt;i&gt;Fig 4. All-to-all four nodes&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;Tungsten &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/TRCMultiMasterInstallation#Multi-Master_Installation"&gt;Multi-Master Installation&lt;/a&gt; solves this problem. It allows me to create topologies where every node replicates to every other node. Looking at the three-node scheme, it appears a straightforward solution. When we add one node, though, we see that the amount of network traffic grows quite a lot. The double sided arrows mean that there is a replication service at each end of the line, and two open data channels. When we move from three nodes to four, we double the replication services and the channels needed to sustain the scheme.  For several months, I was content with this. I thought: it is heavy, but it works, and it's way more than what you can do with native replication, especially if you consider that you can have &lt;a href="http://scale-out-blog.blogspot.com/2011/08/practical-multi-master-replication.html"&gt;a practical way of preventing conflicts using Shard Filters&lt;/a&gt;.  But that was not enough. Something kept gnawing at me, and from time to time I experimented with Tungsten Replicator huge flexibility to create new topologies. But the star kept eluding me. Until … Until, guess what? a customer asked for it. The problem suddenly ceased to be a personal whim, and it became a business opportunity. Instead of looking at the issue in the idle way I often think about technology, I went at it with practical determination. What failed when I was experimenting in my free time was that either the pieces did not glue together the way I wanted, or I got an endless loop. Tungsten Replicator has a set of components that are conceptually simple. You deploy a pipeline between two points, open the tap, and data starts flowing in one direction. Even with multiple masters replication, the principle is the same. You deploy many pipes, and each one has one purpose only.   &lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt; &lt;img src="http://lh5.ggpht.com/-vz42MY4fGwQ/TrPFT4Me36I/AAAAAAAABOQ/AJ2ZI2VkGc8/replication_5_star_topology_3_rays.png?imgmax=800" alt="Replication 5 star topology 3 rays" title="star topology 3 rays" border="0" width="267" height="230" /&gt; &lt;p align="center"&gt;&lt;i&gt;Fig 5. All-masters star topology&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;In the star topology, however, you need to open more taps, but not too many, as you need to avoid the data looping around. The recipe, as it turned out, is to create a set of bi-directional replication systems, where you enable the central node slave services to get changes only from a specific master, and the slave services on the peripheral nodes to accept changes from any master. It was as simple as that.   There are, of course, benefits and drawbacks with a star topology, compared to a all-replicate-to-all design. In the star topology, we create a single point of failure. If the central node fails, replication stops, and the central node needs to be replaced. Instead, the all-to-all design has no weaknesses. Its abundance of connections makes sure that, if a node fails, the system continues working without any intervention. There is no need for fail-over.    &lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt; &lt;img src="http://lh4.ggpht.com/-5Kmmu6-vfoc/TrPFXD9sBlI/AAAAAAAABOo/rL9Lu2AZz7M/replication_6_all_to_all_extending.png.png?imgmax=800" alt="Replication 6 all to all extending png" title="all to all extending" border="0" width="317" height="331" /&gt; &lt;p align="center"&gt;&lt;i&gt;Fig 6. extending an all-to-all topology&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt; &lt;img src="http://lh3.ggpht.com/-QXoDHeUhoa8/TrPFWKqLGmI/AAAAAAAABOg/TZcUBUFOVg4/replication_7_star_extending.png?imgmax=800" alt="Replication 7 star extending" title="star extending" border="0" width="315" height="321" /&gt; &lt;p align="center"&gt;&lt;i&gt;Fig 7. Extending a star topology&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;However, there is a huge benefit in the node management. If you need to add a new node, it costs two services and two connections, while the same operation in the all-to-all replication costs 8 services and 8 connections.  With the implementation of this topology, a new challenge has arisen. While conflict prevention by sharding is still possible, this is not the kind of scenario where you want to apply it. We have another conflict prevention mechanism in mind, and this new topology is a good occasion make it happen.  YMMV. I like the additional choice. There are cases where a all-replicate-to-all topology is still the best option, and there are cases where a star topology is more advisable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-651168652658416419?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/651168652658416419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=651168652658416419' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/651168652658416419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/651168652658416419'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/11/replication-multiple-masters-stars.html' title='Replication stars'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-ZdubvXSXpyI/TrPFPlH8WJI/AAAAAAAABNw/ndLQKrtpCms/s72-c/replication_1_master_slave.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1087210632409111581</id><published>2011-10-18T23:52:00.001+02:00</published><updated>2011-10-18T23:52:03.278+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='london'/><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='percona'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='free software'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>Tungsten Replicator and MySQL Sandbox at Percona Live London 2011</title><content type='html'>&lt;table border="0" cellpadding="10" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;a href='http://www.percona.com/live/london-2011/'&gt;&lt;img src='http://www.percona.com/static/images/percona-live/London2011/promote/PL_Badge_Large_Speaker.jpg' width='118' height='239' alt='Percona Live MySQL Conference, London, Oct 24th and 25th, 2011' title='Discover the Power of MySQL' /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I will be a speaker at &lt;a href='http://www.percona.com/live/london-2011/'&gt;Percona Live - London 2011&lt;/a&gt;, and I am looking forward to the event, which is packed with great content. A whopping 40 session of MySQL content, plus 3 keynotes and 14 tutorials. It's enough to keep every MySQL enthusiast busy.Continuent speakers will be particularly busy, as between me and &lt;a href="http://scale-out-blog.blogspot.com/"&gt;Robert Hodges&lt;/a&gt;, we will be on stage four times on Tuesday, October 25th. &lt;ul&gt;&lt;li&gt;Robert, at 10:15am: &lt;a href="http://www.percona.com/live/london-2011/session/teaching-an-old-dog-new-tricks-tungsten-enterprise-clusters-for-mysql/"&gt;Teaching an Old Dog New Tricks: Tungsten Enterprise Clusters for MySQL&lt;/a&gt;, Bishopsgate Suite&lt;/li&gt;&lt;li&gt;Robert, at 1:30pm: &lt;a href="http://www.percona.com/live/london-2011/session/mysql-parallel-replication-in-5-minutes-or-less/"&gt;MySQL Parallel Replication in 5 Minutes or Less&lt;/a&gt;, Newgate Suite&lt;/li&gt;&lt;li&gt;me, at 2:30pm: &lt;a href="http://www.percona.com/live/london-2011/session/mysql-replication-outside-the-box-multiple-masters-fan-in-parallel-apply/"&gt;MySQL Replication outside the box : multiple masters, fan-in, parallel apply&lt;/a&gt;, Ludgate Suite&lt;/li&gt;&lt;li&gt;me, at 4:30pm: &lt;a href="http://www.percona.com/live/london-2011/session/mysql-sandbox-a-framework-for-productive-laziness/"&gt;MySQL Sandbox: a framework for productive laziness&lt;/a&gt;,Ludgate Suite&lt;/li&gt;&lt;/ul&gt;This event feels good from the beginning. There are plenty of participants, many names from all over the MySQL community, covering large and small companies, experienced speakers, well known names in the MySQL engineering arena, and a wealth of topics that will make me feel sorry for not being able to attend them all. It's the usual dilemma that attendees have at this kind of conferences. Not so much at Oracle Open World 2011, where there weren't that many MySQL sessions to choose from, although it was great for networking.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;h3&gt;Our talks&lt;/h3&gt;Robert will open the dances with &lt;a href="http://www.percona.com/live/london-2011/session/teaching-an-old-dog-new-tricks-tungsten-enterprise-clusters-for-mysql/"&gt;Teaching an Old Dog New Tricks: Tungsten Enterprise Clusters for MySQL&lt;/a&gt;, a talk about Tungsten Enterprise, my company's commercial product, which is a professional managing tool for demanding companies.Robert, again in the afternoon, with one of the most amazing features of our open source product, Tungsten Replicator: &lt;a href="http://www.percona.com/live/london-2011/session/mysql-parallel-replication-in-5-minutes-or-less/"&gt;MySQL Parallel Replication in 5 Minutes or Less&lt;/a&gt;. This is a feature for large replication systems where the slave can't cope with large data streams, due to the singled-thread MySQL slave. This talk will show how easy is it to plug Tungsten Replicator to a lagging slave, start parallel replication until the lag has been zeroed, and then hand over the control to the native replication again.Then it will be my turn, with a general presentation about Tungsten Replicator, the open source product. I like the idea of calling it &lt;a href="http://www.percona.com/live/london-2011/session/mysql-replication-outside-the-box-multiple-masters-fan-in-parallel-apply/"&gt;MySQL Replication outside the box : multiple masters, fan-in, parallel apply&lt;/a&gt;. The reasoning is that MySQL replication, although wildly successful in the web economy of the last decade, it is also constrained by several limits, which Tungsten, acting outside the boundaries, sets free. This will be a quick intro to Tungsten and its new user-friendly installation, with a few demos.Finally, a classic presentation with some new content, on &lt;a href="http://www.percona.com/live/london-2011/session/mysql-sandbox-a-framework-for-productive-laziness/"&gt;MySQL Sandbox: a framework for productive laziness&lt;/a&gt;. The news is that MySQL Sandbox now supports Percona and MariaDB builds. Again, some demos will be shown, with old and new features mixed together.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1087210632409111581?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1087210632409111581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1087210632409111581' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1087210632409111581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1087210632409111581'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/10/tungsten-replicator-and-mysql-sandbox.html' title='Tungsten Replicator and MySQL Sandbox at Percona Live London 2011'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1234122059737251337</id><published>2011-09-22T22:37:00.001+02:00</published><updated>2011-09-22T22:37:15.209+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='upgrade'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='update'/><category scheme='http://www.blogger.com/atom/ns#' term='recipes'/><title type='text'>Upgrading Tungsten Replicator: as easy as ...</title><content type='html'>When I talked about the usability improvements of Tungsten Replicator, I did not mention the procedure for upgrading.I was reminded about it by a question in the TR mailing list, and since the question was very relevant, I updated the Tungsten Cookbook with some quick &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/TungstenReplicatorCookbook#Upgrading_from_Tungsten_Replicator_2.0.4_to_2.0.5"&gt;upgrading instructions&lt;/a&gt;.A quick upgrading procedure is as important as the installer. Since we release software quite often, either because we have scheduled features to release or because of bug fixes, users want to apply a new release to an existing installation without much fuss. You can do the upgrade with a very quick and painless procedure.Let's suppose that you have installed one Tungsten Replicator cluster using this command:&lt;pre&gt;&lt;br /&gt;#&lt;br /&gt;# using tungsten-replicator 2.0.4&lt;br /&gt;#&lt;br /&gt;TUNGSTEN_HOME=/home/tungsten/installs/master_slave&lt;br /&gt;./tools/tungsten-installer \&lt;br /&gt;  --master-slave \&lt;br /&gt;  --master-host=r1 \&lt;br /&gt;  --datasource-user=tungsten \&lt;br /&gt;  --datasource-password=secret \&lt;br /&gt;  --service-name=dragon \&lt;br /&gt;  --home-directory=$TUNGSTEN_HOME \&lt;br /&gt;  --cluster-hosts=r1,r2,r3,r4 \&lt;br /&gt;  --start-and-report&lt;br /&gt;&lt;/pre&gt;If you want to upgrade to the very latest Tungsten Replicator 2.0.5, build 321, this is what you need to do. &lt;ul&gt;&lt;li&gt;Get the latest tarball, and expand it;&lt;/li&gt;&lt;li&gt;Stop the replicator;&lt;/li&gt;&lt;li&gt;Run the update command (this will also restart the replicator)&lt;/li&gt;&lt;li&gt;Check that the replicator is running again.&lt;/li&gt;&lt;/ul&gt;The actual upgrade command is in bold in the following script.&lt;pre&gt;&lt;br /&gt;#&lt;br /&gt;# using tungsten-replicator 2.0.5-321 (get it from &lt;a href="http://bit.ly/tr20_builds"&gt;bit.ly/tr20_builds&lt;/a&gt;) &lt;br /&gt;#&lt;br /&gt;TUNGSTEN_HOME=/home/tungsten/installs/master_slave&lt;br /&gt;HOSTS=(r1 r2 r3 r4)&lt;br /&gt;for HOST in ${HOSTS[*]} &lt;br /&gt;do &lt;br /&gt;   ssh $HOST $TUNGSTEN_HOME/tungsten/tungsten-replicator/bin/replicator stop &lt;br /&gt;   &lt;b&gt;./tools/update --host=$HOST --user=tungsten --release-directory=$TUNGSTEN_HOME -q &lt;/b&gt;&lt;br /&gt;   $$TUNGSTEN_HOME/tungsten/tungsten-replicator/bin/trepctl -host $HOST services&lt;br /&gt;done&lt;br /&gt;&lt;/pre&gt;One benefit of this procedure, in addition to being brief and effective, is that the previous binaries are preserved.Before the upgrade, you will see:&lt;pre&gt;&lt;br /&gt;$ ls -lh ~/installs/master_slave/ ~/installs/master_slave/releases&lt;br /&gt;/home/tungsten/installs/master_slave/:&lt;br /&gt;total 32K&lt;br /&gt;drwxrwxr-x 3 tungsten tungsten 4.0K Sep 22 22:03 backups&lt;br /&gt;drwxrwxr-x 2 tungsten tungsten 4.0K Sep 22 22:03 configs&lt;br /&gt;drwxrwxr-x 3 tungsten tungsten 4.0K Sep 22 22:03 relay&lt;br /&gt;drwxrwxr-x 4 tungsten tungsten 4.0K Sep 22 22:06 releases&lt;br /&gt;drwxrwxr-x 2 tungsten tungsten 4.0K Sep 22 22:03 service-logs&lt;br /&gt;drwxrwxr-x 2 tungsten tungsten 4.0K Sep 22 22:03 share&lt;br /&gt;drwxrwxr-x 3 tungsten tungsten 4.0K Sep 22 22:03 thl&lt;br /&gt;lrwxrwxrwx 1 tungsten tungsten   75 Sep 22 22:06 tungsten -&gt; &lt;b&gt;/home/tungsten/installs/master_slave/releases/tungsten-replicator-2.0.4&lt;/b&gt;&lt;br /&gt;/home/tungsten/installs/master_slave/releases:&lt;br /&gt;total 8.0K&lt;br /&gt;drwxr-xr-x 6 tungsten tungsten 4.0K Sep 22 22:03 tungsten-replicator-2.0.4&lt;br /&gt;&lt;/pre&gt;The 'tungsten' directory is a symlink to the actual binaries inside the 'releases' directory.After the upgrade, the same directory looks like this:&lt;pre&gt;&lt;br /&gt;ls -lh ~/installs/master_slave/ ~/installs/master_slave/releases&lt;br /&gt;/home/tungsten/installs/master_slave/:&lt;br /&gt;total 32K&lt;br /&gt;drwxrwxr-x 3 tungsten tungsten 4.0K Sep 22 22:03 backups&lt;br /&gt;drwxrwxr-x 2 tungsten tungsten 4.0K Sep 22 22:03 configs&lt;br /&gt;drwxrwxr-x 3 tungsten tungsten 4.0K Sep 22 22:03 relay&lt;br /&gt;drwxrwxr-x 4 tungsten tungsten 4.0K Sep 22 22:06 releases&lt;br /&gt;drwxrwxr-x 2 tungsten tungsten 4.0K Sep 22 22:03 service-logs&lt;br /&gt;drwxrwxr-x 2 tungsten tungsten 4.0K Sep 22 22:03 share&lt;br /&gt;drwxrwxr-x 3 tungsten tungsten 4.0K Sep 22 22:03 thl&lt;br /&gt;lrwxrwxrwx 1 tungsten tungsten   75 Sep 22 22:06 tungsten -&gt; &lt;b&gt;/home/tungsten/installs/master_slave/releases/tungsten-replicator-2.0.5-321&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;/home/tungsten/installs/master_slave/releases:&lt;br /&gt;total 8.0K&lt;br /&gt;drwxr-xr-x 6 tungsten tungsten 4.0K Sep 22 22:03 tungsten-replicator-2.0.4&lt;br /&gt;drwxr-xr-x 6 tungsten tungsten 4.0K Sep 22 22:06 tungsten-replicator-2.0.5-321&lt;br /&gt;&lt;/pre&gt;If you did some manual change to the files in 2.0.4, you will be able to retrieve them. Upgrading from earlier versions of Tungsten Replicator is not as smooth. Since we changed the installation format,  it has become incompatible from previous versions. Clusters running TR 2.0.3 need to be reinstalled manually. The next upgrade, though, will be much faster!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1234122059737251337?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1234122059737251337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1234122059737251337' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1234122059737251337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1234122059737251337'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/upgrading-tungsten-replicator-as-easy.html' title='Upgrading Tungsten Replicator: as easy as ...'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-2986121197183948875</id><published>2011-09-22T12:25:00.001+02:00</published><updated>2011-09-22T12:25:34.931+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>My three MySQL sessions at OOW 2011 - and much more</title><content type='html'>&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.oracleimg.com/ocom/groups/public/@ocom/documents/digitalasset/352034.gif"&gt;&lt;/td&gt;&lt;td&gt;Oracle Open World 2011 is approaching. MySQL is very well represented.Sheeri has put together a simple table of all the &lt;a href="http://technocation.org/files/doc/2011_OOW_MySQL_Content.html"&gt;MySQL sessions at OOW&lt;/a&gt;, which is more handy than the Oracle &lt;a href="http://www.oracle.com/openworld/learn/agenda/index.html"&gt;schedule&lt;/a&gt;.I will be speaking in &lt;b&gt;three sessions&lt;/b&gt; on Sunday, October 2&lt;sup&gt;nd&lt;/sup&gt;.&lt;ul&gt;&lt;li&gt;Sunday, 9am &lt;a href="https://oracleus.wingateweb.com/scheduler/modifySession.do?SESSION_ID=29060"&gt;MySQL: Don't Be a Rookie Forever—Be in Command (Line)&lt;/a&gt;I have given this talk before, as a tutorial at the UC in 2010 and at FrOSCon one month ago. It is one of the most rewarding sessions ever. The attendee were very interested. This will be a short version of the tutorial.&lt;/li&gt;&lt;li&gt;Sunday, 10:15am &lt;a href="https://oracleus.wingateweb.com/scheduler/modifySession.do?SESSION_ID=29021"&gt;&gt;MySQL: Jailbreaking MySQL Replication&lt;/a&gt;.This is related to my job at Continuent. It will a showcase of &lt;a href="http://tungsten-replicator.org"&gt;Tungsten Replicator&lt;/a&gt;, with quick examples of how to build replication clusters with multiple masters, multiple sources, chained clusters, parallel replication.&lt;/li&gt;&lt;li&gt;Sunday, 2:45pm &lt;a href="https://oracleus.wingateweb.com/scheduler/modifySession.do?SESSION_ID=27661"&gt;Bridging MySQL and Oracle Databases with Open Source Replication&lt;/a&gt;.In this session, together with Robert Hodges, I will show how you can replicate from MySQL to Oracle and PostgreSQl using Tungsten Replicator. &lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;There are 47 MySQL sessions in total. You can see them in &lt;a href="http://technocation.org/files/doc/2011_OOW_MySQL_Content.html"&gt;Technocation summary&lt;/a&gt; or get the &lt;a href="http://www.oracle.com/openworld/oow11-focuson-mysql-486114.pdf"&gt;Oracle focus on mysql pdf&lt;/a&gt;.There are huge expo halls at OOW. Among them, there is also MySQL. The &lt;b&gt;MySQL Community booth&lt;/b&gt;, manned by volunteers, is at Moscone West, Level 2 Lobby. Other MySQL booths are listed in the Technocation summary.On the social side, Oracle ACEs will have a dinner on Sunday evening, and MySQL Oracle ACEs will have another gathering on Monday evening.On Tuesday, October 4th, there is a &lt;a href="http://www.oracle.com/webapps/events/ns/EventsDetail.jsp?p_eventId=140041&amp;src=7314534&amp;src=7314534&amp;Act=83&amp;evite=83"&gt;MySQL Community reception&lt;/a&gt;. It's free. You don't need a OOW pass to attend, but &lt;a href="http://www.oracle.com/webapps/events/ns/EventsDetail.jsp?p_eventId=140041&amp;src=7314534&amp;src=7314534&amp;Act=83&amp;evite=83"&gt;registration &lt;/a&gt; is required.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-2986121197183948875?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/2986121197183948875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=2986121197183948875' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2986121197183948875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2986121197183948875'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/my-three-mysql-sessions-at-oow-2011-and.html' title='My three MySQL sessions at OOW 2011 - and much more'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1625062890782355678</id><published>2011-09-19T02:16:00.001+02:00</published><updated>2011-09-19T02:16:47.970+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='topology'/><title type='text'>Chaining Replication Clusters</title><content type='html'>MySQL built-in replication includes a concept called &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/replication-solutions-performance.html"&gt;relay slave&lt;/a&gt;, which allows you to create hierarchical database clusters.You can do the same thing with Tungsten, and this can be done in more than one way.Let's start with two distinct clusters. We can follow the recipes in the &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/TungstenReplicatorCookbook"&gt;Tungsten Cookbook&lt;/a&gt; to install a  &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/TungstenReplicatorCookbook?ts=1316383774&amp;updated=TungstenReplicatorCookbook#Install_a_master_/_slave_cluster"&gt;master / slave cluster&lt;/a&gt; in three separate hosts and a &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/TungstenReplicatorCookbook?ts=1316383774&amp;updated=TungstenReplicatorCookbook#Install_Tungsten_master/slave_replication_in_a_sandbox"&gt;Tungsten sandbox&lt;/a&gt; containing another master/slave cluster.Now, we want to make the master in the sandbox a slave of the master in the first cluster, as illustrated in the figure below.&lt;img src="http://lh5.ggpht.com/-bNz4IMFt-N0/TnaJ52wf-OI/AAAAAAAABNY/ZTOAzPdyjgY/chaning_clusters_master_to_master.png?imgmax=800" alt="Chaning clusters master to master" title="chaning_clusters_master_to_master.png" border="0" width="408" height="559" /&gt;Notice that the recipe works in exactly the same way for two distinct clusters on separate hosts. We are using one sandbox to minimize the number of hosts involved.To install the bridge between the two cluster, you go to the directory where Tungsten was installed for the master in the sandbox, and run &lt;i&gt;./tools/configure-service&lt;/i&gt;. The purpose of this command is to create a second service in the master, a service that will act as a slave, and fetch data from the other cluster.To do so, we need to provide some information to the service installer, the most important of which are:&lt;ul&gt;&lt;li&gt;the local-service-name, a.k.a. &lt;i&gt;who's the boss&lt;/i&gt;, will tell the replicator that this service will live with the 'tsandbox' service, which is the local master. &lt;/li&gt;&lt;li&gt;the &lt;i&gt;role&lt;/i&gt; tells the replicator that this service will fetch data;&lt;/li&gt;&lt;li&gt;the &lt;i&gt;master-thl-host&lt;/i&gt; is the address where to find a master capable of feeding data to this new slave; &lt;/li&gt;&lt;li&gt;the &lt;i&gt;master-thl-port&lt;/i&gt; and &lt;i&gt;thl-port&lt;/i&gt; options make sure that the service uses one port for its own dispatching and another one to get data from the master.&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;br /&gt;cd $HOME/tsb2/db1&lt;br /&gt;./tungsten/tools/configure-service -C \&lt;br /&gt;  --local-service-name=tsandbox \&lt;br /&gt;  --thl-port=12111 \&lt;br /&gt;  --role=slave \&lt;br /&gt;  --service-type=remote \&lt;br /&gt;  &lt;b&gt;--master-thl-host=r1&lt;/b&gt; \&lt;br /&gt;  --master-thl-port=2112 \&lt;br /&gt;  --datasource=127_0_0_1 \&lt;br /&gt;  --svc-start \  &lt;br /&gt;  dragon&lt;br /&gt;&lt;/pre&gt;After this connection, every change in the first cluster master will be replicated to all its slaves, one of which happens to be a master, which will then distribute the same data to all its slaves. So we have a cascade hierarchical replication cluster, similar to what we can have with MySQL native replication.But Tungsten can do something more than that. In MySQL replication, you need to enable a slave to become a relay-slave. In Tungsten, you don't need to do it.&lt;img src="http://lh6.ggpht.com/-KSuAOT3Mogo/TnaJ7fLa1zI/AAAAAAAABNc/qn7HItK4P2U/chaning_clusters_slave_to_master.png?imgmax=800" alt="Chaning clusters slave to master" title="chaning_clusters_slave_to_master.png" border="0" width="412" height="558" /&gt;Using a very similar command, I can connect to a slave of the first cluster, instead of the master, and the final result will be exactly the same.&lt;pre&gt;&lt;br /&gt;cd $HOME/tsb2/db1&lt;br /&gt;./tungsten/tools/configure-service -C \&lt;br /&gt;  --local-service-name=tsandbox &lt;br /&gt;  --thl-port=12111 \&lt;br /&gt;  --role=slave \&lt;br /&gt;  --service-type=remote \&lt;br /&gt;  &lt;b&gt;--master-thl-host=r3&lt;/b&gt; \&lt;br /&gt;  --master-thl-port=2112 \&lt;br /&gt;  --datasource=127_0_0_1 \&lt;br /&gt;  --svc-start \  &lt;br /&gt;  dragon&lt;br /&gt;&lt;/pre&gt;In my presentations, I call this feature "slave with an attitude". Thanks to Tungsten global transaction ID, a slave can request data to any host. Since the data is not labeled in terms of log files and position (as it is in MySQL), but in terms of &lt;i&gt;sequence numbers&lt;/i&gt;, a slave ch ask any server for a given sequence number, and that number identifies a transaction unequivocally.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1625062890782355678?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1625062890782355678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1625062890782355678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1625062890782355678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1625062890782355678'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/chaining-replication-clusters.html' title='Chaining Replication Clusters'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/-bNz4IMFt-N0/TnaJ52wf-OI/AAAAAAAABNY/ZTOAzPdyjgY/s72-c/chaning_clusters_master_to_master.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5220115591318568666</id><published>2011-09-16T23:33:00.001+02:00</published><updated>2011-09-16T23:33:33.695+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='best practices'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='multi-master'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='cookbook'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='topology'/><category scheme='http://www.blogger.com/atom/ns#' term='recipes'/><title type='text'>Quick recipes for database cluster building</title><content type='html'>One lesson learned in more than two decades working in this industry is that most of the IT professionals are impatient, want to achieve results immediately, and, most importantly, they &lt;i&gt;don't read documentation&lt;/i&gt;. Much as the average geek is happy to answer many requests with a dismissive &lt;a href="http://en.wikipedia.org/wiki/RTFM"&gt;RTFM&lt;/a&gt;, the same geeks are not as diligent when it comes to learning about new or updated technologies.For this reason, there is a kind of documentation that is very much appreciated by busy and impatient professionals: cookbooks. And I am not talking about food. Geeks are not known for being cooks &lt;sup&gt;&lt;small&gt;(1)&lt;/small&gt;&lt;/sup&gt; and they like fast food. I am talking about collection of technical recipes, short articles where a problem is briefly stated, and a direct solution is shown.Working with Tungsten Replicator, I am constantly amazed at all the things you can do with it, and at the same time, I am amazed at how so few people read the &lt;a href="http://continuent.com/downloads/documentation"&gt;documentation&lt;/a&gt;. Since I want more users to be aware of the goodies, and being aware of the geeks' aversion to regular docs, I have started putting together a &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/TungstenReplicatorCookbook"&gt;Tungsten Replicator Cookbook&lt;/a&gt;, where users can quickly find the recipe to build their cluster of choice.The problem is stated in one short paragraph, and the solution is outlined with code in the shortest possible way. Can't get any lazier than this! Or maybe you can, but I haven't reached that level yet. I hope I have found a good balance.Some of the recipes that the cookbook offers are:&lt;ul&gt;&lt;li&gt;Install a master / slave cluster&lt;/li&gt;&lt;li&gt;Install a master slave directory with customized parameters&lt;/li&gt;&lt;li&gt;Install more than one Tungsten Replicator in one host&lt;/li&gt;&lt;li&gt;Install a direct slave with parallel replication&lt;/li&gt;&lt;li&gt;Taking over replication from a MySQL slave in direct mode&lt;/li&gt;&lt;li&gt;Install bi-directional replication&lt;/li&gt;&lt;li&gt;Install bi-directional replication with additional slave&lt;/li&gt;&lt;li&gt;Install a three masters replication&lt;/li&gt;&lt;li&gt;Install a four masters replication&lt;/li&gt;&lt;li&gt;Modify one or more properties with the installer&lt;/li&gt;&lt;li&gt;Add one slave to an existing master&lt;/li&gt;&lt;/ul&gt;In addition to the cookbook, we have inaugurated a sample of another popular literary genre, namely &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/Troubleshooting"&gt;Troubleshooting&lt;/a&gt; recipes.When things go wrong (and they usually do when you are dealing with something new, you want a quick answer to your problem. These troubleshooting items are aimed at making such quick answer readily available. Both projects are moving targets. We will adjust as the project grows. Contributions and comments are welcome. If you have suggestions on how to improve these documents, you can use the &lt;a href="http://groups.google.com/group/tungsten-replicator-discuss"&gt;mailing list&lt;/a&gt;.&lt;sup&gt;&lt;small&gt;(1)&lt;/small&gt;&lt;/sup&gt; &lt;small&gt;With some notable exception, I must say. I have a reputation as a good cook. But then, I represent a minority in so many ways. &lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5220115591318568666?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5220115591318568666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5220115591318568666' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5220115591318568666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5220115591318568666'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/quick-recipes-for-database-cluster.html' title='Quick recipes for database cluster building'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1561437695262142954</id><published>2011-09-16T10:01:00.002+02:00</published><updated>2011-09-16T10:01:21.122+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><title type='text'>Welcome, MySQL commercial extensions</title><content type='html'>I saw yesterday that MySQL has finally done the right thing, and announced &lt;a href="http://blogs.oracle.com/MySQL/entry/new_commercial_extensions_for_mysql"&gt;new commercial extensions&lt;/a&gt;.&lt;br /&gt;What this means is that paying customers receive something more than users who get the community edition for free.&lt;br /&gt;Believe it or not, when I was working in the community team at MySQL, I was already an advocate of this solution. You may see a contradiction, but there isn't. I would like to explain how this works.&lt;br /&gt;&lt;br /&gt;An open source product needs to be developed. And the developers need to get paid. Ergo, the company needs to make money from that product if it wants to continue developing it. Either that, or the company needs to sell something else to pay the bills. (Let's not get into the argument that a &lt;i&gt;pure&lt;/i&gt; open source project with universal participation is better, faster, or more marvelous: MySQL was never that, not with Oracle, not with Sun, and not when it was an independent company. If you want a extra-super-ultra open project, go with Drizzle. With MySQL, we need to continue reasoning with the raw material at hand.)&lt;br /&gt;When MySQL was scaling its business, it realized that many customers were not willing to pay for support and consulting alone. To expand the business beyond the simple offer of services, the company created MySQL Network, which soon evolved into MySQL Enterprise, with the addition of the MySQL Monitoring tools and a fast upgrade plan. This was a good proposal for small to medium customers, but not as good for customers with large installations. When you deploy thousands of MySQL servers, you really don't want to upgrade every month. Anyway, for some time, the value proposition from MySQL was that the community users would get one release twice a year, and the paying customers would get one every month.&lt;br /&gt;As a community manager, I strongly objected to that formula, not only because it hurts the community, but also because it hurts customers. When the release is exposed to millions of free users before it goes to the paying customers, chances are that serious bugs are discovered by the community and fixed in due time, before it hurts a high profile customer and needs to be fixed in a hurry at higher cost.  One of the main values of MySQL is that it's that its large community adoption and feedback increases stability. Fortunately, I was not the only one who believed that larger distribution is valuable for customers, and the decision was reversed at the end of 2008.&lt;br /&gt;In that period, I and other employees recommended a different value proposition for our customers. Instead of selling fast upgrade plans (which become a liability), MySQL could develop some reserved features that would be given only to paying customers.&lt;br /&gt;There are two problems with reserved features, though: you need to develop them internally. You can't start them in the open, asking the community to test them for bugs, and then give them only to customers when they are ready (There was a faux pas in that direction in early 2008, but it was promptly retracted). These features must be developed as closed source, and tested only internally. The second problem is that MySQL had little internal QA manpower when this discussion arose.&lt;br /&gt;There was another issue, namely that the code base for the next intended version (the fabled 6.0) was brittle. After 2 years in alpha stage, there was little to show for the effort. In parallel to the Oracle acquisition, two important things happened: version 6 was abandoned, and a new effort was started, using the more stable version 5.x as a code base, and a new developing model was launched, based on milestones and robustness.&lt;br /&gt;This new foundation, combined with the injection of experienced QA personnel from the ranks of Sun and Oracle, made the project ready to offer reserved features to customers, while continuing the development of a lot more features for the community edition.&lt;br /&gt;From a community standpoint, &lt;b&gt;I welcome the commercial extensions&lt;/b&gt;. It means that the MySQL project will get more revenues, and be able to sustain the public release more easily. In my opinion it's the logical evolution of the project, and it's what MySQL should have done already years ago if it had had the manpower.&lt;br /&gt;There are already detractors who see this release as a sign of the apocalypse. They probably want to see only this one feature in the commercial arena, dismissing the dozens of new features released to the general public under Oracle stewardship. I refuse to enroll in the chorus of critics who judge Oracle on prejudice. I am so far satisfied with what Oracle has done with MySQL. My opinion is based on facts, and since the facts are in favor of the community, I am pleased to say so. If future facts will make me change my opinion, I will say it. But now, I want to say &lt;b&gt;thank you&lt;/b&gt; to the MySQL team at Oracle!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1561437695262142954?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1561437695262142954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1561437695262142954' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1561437695262142954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1561437695262142954'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/welcome-mysql-commercial-extensions.html' title='Welcome, MySQL commercial extensions'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-2156679551085671916</id><published>2011-09-08T18:38:00.001+02:00</published><updated>2011-09-08T18:44:28.374+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>The happiness of failing installations</title><content type='html'>When you set-up the same software several times (for you or for your customers), you want that software to install quickly and reliably, and you are generally happy when everything works as expected.&lt;br /&gt;In this context, a &lt;i&gt;failing installation&lt;/i&gt; is when the installation process exits unexpectedly, and you are left with an error message and the prospect of looking at the manual to find out what was it.&lt;br /&gt;&lt;br /&gt;A failing installation is unpleasant, you'd say, and I concur. But do you know what's more unpleasant than a failing installation? It's an installation that succeeds, only to fail silently the first time you try using the application.&lt;br /&gt;&lt;br /&gt;Looking at this enhanced definition, it is no surprise that I assert to find happiness in failure. And I have practical reasons for my claim. When I first tried &lt;a href="http://tungsten-replicator.org"&gt;Tungsten Replicator&lt;/a&gt; installation, it succeeded. And to my chagrin, the application did not work. I had to dig the reason for not working from the logs, and from that reason I had to figure out what I had done wrong. For example, the log might say "file not found mysql-bin.000003", and from that piece of information I had to figure out that I forgot to make the binary logs directory group readable, so that the 'tungsten' user could see the logs.&lt;br /&gt;But a "successful" installation with later failure often meant that a clean shut down was not possible, and then I had to become an expert at cleaning up messy installations.&lt;br /&gt;The next installation may get past the failure point, and possibly fail (again silently) for a different reason. Sometimes, I had to install four or five times until I get to the working and stable point. And then I'd install on another server, and I made a different mistake (or I forgot to apply the cure for a known mistake) and the stream of successful installations with hidden failures continued for a while.&lt;br /&gt;&lt;br /&gt;With the above reminiscences, I am very happy to report that now you can install Tungsten Replicator with the near assurance that when something goes wrong, the installation does not start, and you are given a clear list of what was wrong. &lt;br /&gt;The &lt;a href="https://s3.amazonaws.com/releases.continuent.com/doc/replicator-2.0.4/html/Tungsten-Installation-Guide-mysql/content/ch03s01.html"&gt;installer&lt;/a&gt; runs a long list of validation probes, and it doesn't stop at the first validation failure. It will try its best to tell you what you should do to reach a satisfactory installation, giving you a detailed list of everything that doesn't match up.&lt;br /&gt;Not only that: the installer checks the requirements on all the servers in your intended cluster, and the installation does not start anywhere until you meet all the requirements in all the servers.&lt;br /&gt;&lt;br /&gt;That's why, when my installation fails, I feel very happy, knowing that I won't have to clean up a messy server, and when I fix the problem that made the installation fail, my application will most certainly work.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-2156679551085671916?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/2156679551085671916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=2156679551085671916' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2156679551085671916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2156679551085671916'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/happiness-of-failing-installations.html' title='The happiness of failing installations'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1778031012501054975</id><published>2011-09-07T00:00:00.001+02:00</published><updated>2011-09-07T00:00:09.502+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='cluster'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='downloads'/><title type='text'>Tungsten Replicator 2.0.4 released: usability and power</title><content type='html'>&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh4.ggpht.com/-LJmSxrmoQ0I/TmaX5p5re8I/AAAAAAAABMM/iWWhZFT-9cc/TR_2_0_4.png?imgmax=800" alt="TR 2 0 4" title="TR_2_0_4.png" border="0" width="350" /&gt;&lt;/td&gt;&lt;td&gt;It has been a bumpy ride, with dozens of issues opened and resolved, but we finally feel that &lt;a href="http://tungsten-replicator.org"&gt;Tungsten Replicator 2.0.4&lt;/a&gt; is ready for prime time.There have been quite a lot of &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/Release_Notes"&gt;changes&lt;/a&gt;. Most notably, the replicator is much faster, especially when it comes to &lt;b&gt;parallel replication&lt;/b&gt;, and it is much easier to install, thanks to its new integrated installer, which can validate all the requirements to install the replicator, and suggest remedies when the requirements aren't met. This new installer is so good, in fact, that calling it &lt;i&gt;installer&lt;/i&gt; is an insult. It is a legitimate &lt;b&gt;cluster builder&lt;/b&gt;, able to install a full fledged cluster from a central location.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;Probably equally important, we have caught up with the &lt;a href="http://www.continuent.com/downloads/documentation"&gt;documentation&lt;/a&gt;, and now you can install several replication topologies following detailed instructions from the docs. You will find both HTML and PDF guides, with the steps to install straight master/slave systems, or direct slave takeover, or bi-directional replication.The binaries are available in the project's &lt;a href="http://code.google.com/p/tungsten-replicator/downloads/list"&gt;Downloads&lt;/a&gt; page. Later on, you will find the most updated (and possibly less bug-infested) binaries in our &lt;a href="http://s3.amazonaws.com/files.continuent.com/builds/nightly/tungsten-2.0-snapshots/index.html"&gt;build server&lt;/a&gt; list.The &lt;a href="http://code.google.com/p/tungsten-replicator/wiki/Release_Notes"&gt;Release_Notes&lt;/a&gt; list all the issues that have been closed since we released 2.0.3. The advanced users will especially appreciate an innovation introduced in the installer, which now allows users to define one or more of &lt;code&gt;--property=key=value&lt;/code&gt;. Using this option wisely, you can now customize the replication properties straight at the start. What used to require several commands and a restart of the replicator right after the installation, now flows smoothly and quickly with one single command.With this release, Tungsten Replicator is closer to become a tool for mass consumption. The old installation method (which we have deprecated and renamed, to discourage anyone from using it) required time, constant attention, and it was unforgiving. The new one will let you make your mistakes freely. If something is amiss anywhere in all the servers where you are installing, it won't install and it will tell you what went wrong. This is probably my favorite feature, because it allows Tungsten to be used by less experienced users.Now it's up to the users. We have no illusion that the product is bug free, and we want to hear from users who try it and report on &lt;a href="http://code.google.com/p/tungsten-replicator/issues/list"&gt;Issues&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1778031012501054975?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1778031012501054975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1778031012501054975' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1778031012501054975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1778031012501054975'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/tungsten-replicator-204-released.html' title='Tungsten Replicator 2.0.4 released: usability and power'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-LJmSxrmoQ0I/TmaX5p5re8I/AAAAAAAABMM/iWWhZFT-9cc/s72-c/TR_2_0_4.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-235444998470257614</id><published>2011-09-04T23:34:00.001+02:00</published><updated>2011-09-04T23:34:05.270+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='admin'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='information_schema'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Finding tables without primary keys</title><content type='html'>I was checking a third party server, and I needed to find if there were tables without primary keys. This is important to know, not only because the lack of primary keys affects performance and data accuracy in general, but also because in &lt;a href="http://dev.mysql.com/doc/refman/5.5/en/replication-formats.html"&gt;row-based replication&lt;/a&gt; performance can degrade beyond belief when updating tables without primary keys.Anyway, I did not remember off the bat any method to get this information from a server with thousands of tables, and thus I went to find a solution on my own.My first instinct called for using the &lt;code&gt;COLUMNS&lt;/code&gt; table from the &lt;code&gt;INFORMATIOn_SCHEMA&lt;/code&gt;, and so I came up with this query, where I sum the number of columns that are inside either a PRIMARY or UNIQUE key and filter only the ones where such sum is zero (i.e. no primary or unique keys):&lt;pre&gt;&lt;br /&gt;&lt;strong&gt;select&lt;/strong&gt; &lt;br /&gt;    table_schema,table_name &lt;br /&gt;&lt;strong&gt;from&lt;/strong&gt;  &lt;br /&gt;    information_schema.columns  &lt;br /&gt;&lt;strong&gt;group by &lt;/strong&gt;&lt;br /&gt;    table_schema,table_name   &lt;br /&gt;&lt;strong&gt;having&lt;/strong&gt; &lt;br /&gt;    &lt;strong&gt;sum&lt;/strong&gt;(&lt;strong&gt;if&lt;/strong&gt;(column_key &lt;strong&gt;in&lt;/strong&gt; ('PRI','UNI'), 1,0)) = 0;&lt;br /&gt;&lt;/pre&gt;This query got the job done, and it was quite quick as well.Then, since I was chatting with &lt;a href="http://palominodb.com/"&gt;Sheeri Cabral&lt;/a&gt; about other matters, I asked her if she could come up with an alternative solution. She suggested a &lt;code&gt;LEFT JOIN&lt;/code&gt; between the &lt;code&gt;information_schema.tables&lt;/code&gt; and &lt;code&gt;information_schema.statistics&lt;/code&gt;, which I translated into this query:&lt;pre&gt;&lt;br /&gt;&lt;strong&gt;select&lt;/strong&gt; &lt;br /&gt;    t.table_schema, t.table_name &lt;br /&gt;&lt;strong&gt;from&lt;/strong&gt; &lt;br /&gt;    information_schema.tables  t &lt;br /&gt;    &lt;strong&gt;left join&lt;/strong&gt; information_schema. statistics s &lt;br /&gt;       &lt;strong&gt;on&lt;/strong&gt; t.table_schema=s.table_schema &lt;strong&gt;and&lt;/strong&gt; t.table_name=s.table_name &lt;br /&gt;       &lt;strong&gt;and&lt;/strong&gt; s.non_unique=0 &lt;br /&gt;&lt;strong&gt;where&lt;/strong&gt; &lt;br /&gt;    s.table_name &lt;strong&gt;is null&lt;/strong&gt;;&lt;br /&gt;&lt;/pre&gt;This query works on the principle that it removes from the tables list all the ones for which there is no corresponding table in the &lt;code&gt;statistics&lt;/code&gt; table.This query also works. Using both queries in a relatively empty server did not show any significant difference. But since I knew that I had to use this method on a very busy server, with a lot of tables, I quickly created 1,000 databases, each containing 5 tables, two of which did not have any primary or unique key.Now came the first surprise.The query with &lt;code&gt;GROUP BY&lt;/code&gt; took about 0.5 seconds, while the one using &lt;code&gt;LEFT JOIN&lt;/code&gt; used 11 seconds.I was about to congratulate myself for my acumen, when I realized that, in addition to schema and table names, I also needed the table &lt;code&gt;engine&lt;/code&gt;.For the second query, that is not a problem. Adding the engine to the columns list works OK, and the query runs in 11 seconds like before.The first query, though, can't list the engine. There is no 'engine' in the &lt;code&gt;COLUMNS&lt;/code&gt; table. So I needed a JOIN. Thus my query became&lt;pre&gt;&lt;br /&gt;&lt;strong&gt;select&lt;/strong&gt; &lt;br /&gt;    t.table_schema,t.table_name,engine &lt;br /&gt;&lt;strong&gt;from&lt;/strong&gt; &lt;br /&gt;    information_schema.tables t &lt;br /&gt;    &lt;strong&gt;inner join&lt;/strong&gt; information_schema .columns c  &lt;br /&gt;        &lt;strong&gt;on&lt;/strong&gt; t.table_schema=c.table_schema &lt;strong&gt;and&lt;/strong&gt; t.table_name=c.table_name &lt;br /&gt;&lt;strong&gt;group by&lt;/strong&gt; &lt;br /&gt;    t.table_schema,t.table_name   &lt;br /&gt;&lt;strong&gt;having&lt;/strong&gt; &lt;br /&gt;    &lt;strong&gt;sum&lt;/strong&gt;(&lt;strong&gt;if&lt;/strong&gt;(column_key &lt;strong&gt;in&lt;/strong&gt; ('PRI','UNI'), 1,0)) =0;&lt;br /&gt;&lt;/pre&gt;Guess what? This query ran in 17 seconds (!). So much for my instinct!Joins without keys are not efficient in MySQL, and tables in the information schema are no exception.If anyone has a more efficient method of getting a list of tables without primary key (the list including schema name, table name, and engine), I am curious to know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-235444998470257614?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/235444998470257614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=235444998470257614' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/235444998470257614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/235444998470257614'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/finding-tables-without-primary-keys.html' title='Finding tables without primary keys'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-2966730175054367808</id><published>2011-09-02T10:40:00.000+02:00</published><updated>2011-09-02T10:40:31.123+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='primary key'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Primary keys from experience</title><content type='html'>From time to time I see articles in defense of natural primary keys against surrogate keys.I don't take an immovable stand on either side, as I have seen good cases for both. In general, I like the idea of a natural primary key, when I see one that it is really natural. Quite often, though, a natural primary key has proved itself faulty. And most of the times, when such faults happened, it was because of limited understanding of the data. I like to describe this kind of misinformation as &lt;b&gt;data analysis culture clash&lt;/b&gt;.When choosing a natural primary key, one should consider which element, or group of elements, are unique in a given set. Not only that, they must be immutable, at least within that set.For example, in a group of people, we may assume that a combination of name, surname, date and place of birth is a good natural primary key. Well, no. It isn't, for several reasons. Read on for a few real cases.If we rule out the above combination, perhaps we could use the Social Security Number as a valid key? Not really.The fact is that the above assumptions work well if we consider only people from the same country in current times. If we extend our data definition to include people from different countries, or historical records, then the assumption collapses.A practical case: The &lt;b&gt;birth place&lt;/b&gt;. This is a fair assumption. In combination with other elements (e.g.: date of birth, name, and surname) it can provide good basis for unique and immutable records. If you consider people in the United States today, you are right. Even in the UK, or Italy, or France. But try applying this method to places with recent political changes due to war or revolutions, and suddenly the name of the town may suddenly change. What was before VictoryBurg in Oppresslandia is now known as Heroes City in Freelandia. And this happens now, in the 21st century. If your set includes historical data, these occurrences may become frightfully frequent.Speaking of historical times, if you are dealing with really old records, you may want to consider that &lt;b&gt;dates&lt;/b&gt; are less than immutable. The way we count days in most Western countries is called the &lt;a href="http://en.wikipedia.org/wiki/Gregorian_calendar"&gt;Gregorian calendar&lt;/a&gt;, which was adopted by a handful of countries in 1582. Dates before October 5, 1582 and after October 14, 1582 are recorded using two different calendars. It is inconvenient, but if you know that you may avoid wrong date calculations. Simple, isn't it? Not really. If your records include data from different countries, you will have to take into account when this calendar &lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/Gregorian_calendar#Adoption"&gt;was adopted&lt;/a&gt;.  Just to give a few examples, England adopted the Gregorian calendar in 1752, Japan in 1873, Russia in 1918, Turkey in 1926. When dealing with people from different countries, you may be tempted to use &lt;b&gt;citizenship&lt;/b&gt; as an immutable property. That may work, if you consider &lt;i&gt;citizenship at birth&lt;/i&gt; and are prepared to keep the names of not currently existing states. If, instead, you get the citizenship from the employee's passport, you may incur in one or more of the following cases (all happened in practice during my work with an international organization):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Some employees came to work with the passport they had before the political change, and now that the country has split, they have different passports, depending on which side of the new border they live.&lt;/li&gt;&lt;li&gt;Some employees have parents from different countries and are entitled to more than one passport. They came to work initially with one passport, and came again a few year later with a different one because of different benefits.&lt;/li&gt;&lt;li&gt;Some employees started working with a given citizenship, and then they got a different one because of marriage, political asylum, or other legal means.&lt;/li&gt;&lt;li&gt;Some employees became &lt;a href="http://en.wikipedia.org/wiki/Statelessness"&gt;stateless&lt;/a&gt;. The equivalent of  NULL in a table field.&lt;/li&gt;&lt;/ul&gt;Coming to the &lt;b&gt;Social Security Number&lt;/b&gt;, the assumption of uniqueness fails for the same reason that citizenship does. It's even more frequent, because of people working abroad and paying their taxes in a foreign country, so they had two or more SSN or equivalent to show. But this element failed for another reason, i.e. because it is not immutable. It is supposed to be, but in some cases it happens that, due to clerical mistakes, the SSN issued in a given country is wrong, and needs to be changed. It happens in Italy, where your SSN (called "codice fiscale", or fiscal code) must match your name, surname, place, and date of birth. If any of these elements was wrong when the code was generated, the code needs to be done again. It's a painful process that requires a court order, but the result is that the item is not immutable.Other elements that I have seen used wrongly for primary keys, either standalone or as key components, are:  &lt;b&gt;telephone numbers&lt;/b&gt; (they can change, and after being changed they can be assigned to other people), &lt;b&gt;email addresses&lt;/b&gt; (they are unique, but they can easily change, or they can be abandoned when the person changes provider, or company, or both), &lt;b&gt;gender&lt;/b&gt; (it &lt;i&gt;can&lt;/i&gt; change), &lt;b&gt;surname&lt;/b&gt; (it can change, legally, for male and female, depending on country and conditions).Summing up, a sane amount of skepticism should be used when considering if an element can be used in a primary key. Depending on the environment, the element can be safe or it can become a nightmare when the database grows from a neighborhood business to an international venture.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-2966730175054367808?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/2966730175054367808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=2966730175054367808' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2966730175054367808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2966730175054367808'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/09/primary-keys-from-experience.html' title='Primary keys from experience'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5449903946101890188</id><published>2011-08-15T21:36:00.001+02:00</published><updated>2011-08-15T21:36:41.439+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='competition'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='codebits'/><title type='text'>CodeBits - An event of competitive innovation</title><content type='html'>&lt;a href="http://www.flickr.com/photos/datacharmer/4159233901/" title="Codebits 2009 - Pedro and Rupert by datacharmer, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2497/4159233901_7a11a7ee2f.jpg" width="500" height="333" alt="Codebits 2009 - Pedro and Rupert"&gt;&lt;/a&gt;It was my pleasure and privilege to attend &lt;a href="http://codebits.eu"&gt;Codebits&lt;/a&gt; in 2009. As &lt;a href="http://rpbouman.blogspot.com/2011/08/proposals-for-codebitseu.html"&gt;Roland Bouman says&lt;/a&gt;, its talk choice method is based on public voting, and therefore everyone cha have contribute to the schedule.But that is not the main reason for attending this extraordinary event. It is not just a conference. It's an innovation fest. For 1 and 1/2 days, it's a conference, where the speakers are encouraged to bring to their audience the most innovative and inspiring talks. In the afternoon of the second day, the event becomes a competition, where the teams that have registered will have 24 hours to bring a project to completion, and they have to start and finish within the allotted time. The project can be anything, and I have seen quite a lot of exciting stuff rolling live in the huge pavilion: I could hardly ignore &lt;a href="http://www.flickr.com/photos/datacharmer/4159989264/in/set-72157622932698300"&gt;robotics&lt;/a&gt;, as these little mechanical smurfs were running all over the place and you would have to be careful not to squash them when you walked.There was plenty of occasions for  &lt;a href="http://www.flickr.com/photos/datacharmer/4157857932/in/set-72157622932698300&gt;making hardware&lt;/a&gt;, with workshops and places to practice your skills and give shape to your ideas.All over the place you could see the &lt;a href="http://www.flickr.com/photos/datacharmer/4162869484/in/set-72157622932698300"&gt;planning of great projects&lt;/a&gt;, together with attempts at &lt;a href="http://www.flickr.com/photos/datacharmer/4159233591/in/set-72157622932698300"&gt;improving social relations&lt;/a&gt;, and mixing up with &lt;a href="http://www.flickr.com/photos/datacharmer/4157099065/in/set-72157622932698300"&gt; big brother&lt;/a&gt;.There were projects based on &lt;a href="http://www.flickr.com/photos/datacharmer/4159233313/in/set-72157622932698300"&gt;3D printing&lt;/a&gt;, and less broad projects like &lt;a href="http://www.flickr.com/photos/datacharmer/4159232561/in/set-72157622932698300"&gt;all-seasons keyboards&lt;/a&gt;.A very popular session, followed by practical workshops was &lt;a href="http://www.flickr.com/photos/datacharmer/4159991766/in/set-72157622932698300"&gt;lock picking&lt;/a&gt;. I attended one of them, learned how to pick simple and less simple locks, and I brought home some &lt;a href="http://www.flickr.com/photos/datacharmer/4162108385/in/set-72157622932698300"&gt;lockpicking tools&lt;/a&gt;.On a more technical level, I was there with &lt;a href="http://www.flickr.com/photos/datacharmer/4157857856/in/set-72157622932698300"&gt;Lenz Grimmer and Kai Seidler&lt;/a&gt;, we &lt;a href="http://www.flickr.com/photos/datacharmer/4157857720/in/set-72157622932698300"&gt;spoke about MySQL and other cool things&lt;/a&gt;, and we had lots of fun for three days.Besides the teams hacking away at their projects, there were several teams showcasing technology that had been developed by winners of the previous years, such as 3D television and intelligent phone networks. In short, This was an inspiring event, which I can warmly recommend.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5449903946101890188?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5449903946101890188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5449903946101890188' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5449903946101890188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5449903946101890188'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/08/codebits-event-of-competitive.html' title='CodeBits - An event of competitive innovation'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2497/4159233901_7a11a7ee2f_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-7937723470921980252</id><published>2011-08-11T18:19:00.002+02:00</published><updated>2011-08-11T18:20:28.714+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='logs'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='remote'/><category scheme='http://www.blogger.com/atom/ns#' term='innovation'/><title type='text'>Usability improvements in Tungsten Replicator 2.0.4</title><content type='html'>If you love a software product, you should try to improve it, and not be afraid of criticizing it.  This principle has guided me with MySQL (where I have submitted many usability bugs, and discussed interface with developers for years), and it proves true for &lt;a href="http://tungsten-replicator.org"&gt;Tungsten Replicator&lt;/a&gt; as well. When I started working at Continuent, while I was impressed by the technology, I found the installation procedure and the product logs quite discouraging. I would almost say disturbing. Fortunately, my colleagues have agreed on my usability focus, and we can enjoy some tangible improvements. I have already mentioned the &lt;a href="http://datacharmer.blogspot.com/2011/06/getting-started-with-tungsten.html"&gt;new installation procedure&lt;/a&gt;, which requires just one command to install a full master/slave cluster.  I would like to show how you can use the new installer to deploy a multiple source replication topology like the following:  &lt;img src="https://lh6.googleusercontent.com/_gVfZHGgf5LA/TXO04pRkW0I/AAAAAAAABEE/Ws3-Py7RMdE/Tungsten_multi_source_replication.png" width="500" title="Multiple source replication"&gt;  The first step is to install one master in each node. I can run the commands from node #4, which is the one that will eventually receive the updates from the remote masters, and where I need to install the slave services:  &lt;pre&gt;TUNGSTEN_BASE=$HOME/newinst&lt;br /&gt;SERVICES=(alpha bravo charlie delta)&lt;br /&gt;REPLICATOR=$TUNGSTEN_BASE/tungsten/tungsten-replicator/bin/replicator&lt;br /&gt;&lt;br /&gt;for N in 1 2 3 4&lt;br /&gt;do&lt;br /&gt;    INDEX=$(($N-1))&lt;br /&gt;&lt;br /&gt;  ./tools/tungsten-installer \&lt;br /&gt;    --master-slave \&lt;br /&gt;    --master-host=qa.r$N.continuent.com \&lt;br /&gt;    --datasource-user=tungsten \&lt;br /&gt;    --datasource-password=secret \&lt;br /&gt;    --service-name=${SERVICES[$INDEX]} \&lt;br /&gt;    --home-directory=$TUNGSTEN_BASE \&lt;br /&gt;    --cluster-hosts=qa.r$N.continuent.com \&lt;br /&gt;    --start-and-report&lt;br /&gt;done&lt;br /&gt;&lt;/pre&gt;The above loop will install a master (remotely or locally) in the four servers.  Then I need to create the slave services. To do it, I use the updated &lt;code&gt;configure-service&lt;/code&gt; in the &lt;code&gt;tools&lt;/code&gt; directory.  &lt;pre&gt;TUNGSTEN_TOOLS=$TUNGSTEN_BASE/tungsten/tools&lt;br /&gt;COMMON_OPTIONS='-C -q &lt;br /&gt;    --local-service-name=delta &lt;br /&gt;    --role=slave &lt;br /&gt;    --service-type=remote &lt;br /&gt;    --allow-bidi-unsafe=true &lt;br /&gt;    --datasource=qa_r4_continuent_com' &lt;br /&gt;&lt;br /&gt;$TUNGSTEN_TOOLS/configure-service $COMMON_OPTIONS --master-host=qa.r1.continuent.com  alpha &lt;br /&gt;$TUNGSTEN_TOOLS/configure-service $COMMON_OPTIONS --master-host=qa.r2.continuent.com  bravo&lt;br /&gt;$TUNGSTEN_TOOLS/configure-service $COMMON_OPTIONS --master-host=qa.r3.continuent.com  charlie &lt;br /&gt;&lt;br /&gt;$TUNGSTEN_BASE/tungsten/tungsten-replicator/bin/replicator restart&lt;br /&gt;$TUNGSTEN_BASE/tungsten/tungsten-replicator/bin/trepctl services&lt;br /&gt;&lt;/pre&gt;These commands create the slave services locally in Delta. After restarting the replicator, a simple test will be creating something different in each master, and check that the data has replicated to the single slave.  The latest improvement in matter of usability is the simplification of the replicator logs. Until a few days ago, if you had an error in the replicator, you would get a long list of not exactly helpful stuff. For example, if I create a table in a slave, and then create the same table in the master, I will break replication. The extended log would produce something like this:  &lt;pre&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | 2011-08-11 18:10:52,216 [tsandbox - q-to-dbms-0] ERROR pipeline.SingleThreadStageTask Event application failed: seqno=1 fragno=0 message=java.sql.SQLException: Statement failed on slave but succeeded on master&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | 2011-08-11 18:10:52,217 [tsandbox - Event dispatcher thread] ERROR management.OpenReplicatorManager Received error notification, shutting down services: Event application failed: seqno=1 fragno=0 message=java.sql.SQLException: Statement failed on slave but succeeded on master&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | com.continuent.tungsten.replicator.applier.ApplierException: java.sql.SQLException: Statement failed on slave but succeeded on master&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at com.continuent.tungsten.replicator.applier.MySQLDrizzleApplier.applyStatementData(MySQLDrizzleApplier.java:183)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at com.continuent.tungsten.replicator.applier.JdbcApplier.apply(JdbcApplier.java:1233)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at com.continuent.tungsten.replicator.applier.ApplierWrapper.apply(ApplierWrapper.java:101)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at com.continuent.tungsten.replicator.pipeline.SingleThreadStageTask.runTask(SingleThreadStageTask.java:498)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at com.continuent.tungsten.replicator.pipeline.SingleThreadStageTask.run(SingleThreadStageTask.java:155)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at java.lang.Thread.run(Unknown Source)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | Caused by: java.sql.SQLException: Statement failed on slave but succeeded on master&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at com.continuent.tungsten.replicator.applier.MySQLDrizzleApplier.applyStatementData(MySQLDrizzleApplier.java:139)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       ... 5 more&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | Caused by: java.sql.SQLSyntaxErrorException: Table 't1' already exists&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at org.drizzle.jdbc.internal.SQLExceptionMapper.get(SQLExceptionMapper.java:78)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at org.drizzle.jdbc.DrizzleStatement.executeBatch(DrizzleStatement.java:930)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at com.continuent.tungsten.replicator.applier.MySQLDrizzleApplier.applyStatementData(MySQLDrizzleApplier.java:125)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       ... 5 more&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | Caused by: org.drizzle.jdbc.internal.common.QueryException: Table 't1' already exists&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at org.drizzle.jdbc.internal.mysql.MySQLProtocol.executeQuery(MySQLProtocol.java:500)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at org.drizzle.jdbc.internal.mysql.MySQLProtocol.executeBatch(MySQLProtocol.java:546)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       at org.drizzle.jdbc.DrizzleStatement.executeBatch(DrizzleStatement.java:917)&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 |       ... 6 more&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | 2011-08-11 18:10:52,218 [tsandbox - Event dispatcher thread] WARN  management.OpenReplicatorManager Performing emergency service shutdown&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | 2011-08-11 18:10:52,219 [tsandbox - Event dispatcher thread] INFO  pipeline.Pipeline Shutting down pipeline: slave&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | 2011-08-11 18:10:52,219 [tsandbox - q-to-dbms-0] INFO  pipeline.SingleThreadStageTask Terminating processing for stage task thread&lt;br /&gt;INFO   | jvm 1    | 2011/08/11 18:10:52 | 2011-08-11 18:10:52,219 [tsandbox - q-to-dbms-0] INFO  pipeline.SingleThreadStageTask Last successfully processed event prior to termination: seqno=0 eventid=mysql-bin.000002:0000000000000426;20&lt;br /&gt;&lt;/pre&gt;Did you see the reason for the error? No? Neither did I. I would need to open the THL, look for event #1, and determine what it was.  Instead, the new user.log looks like this: &lt;pre&gt;2011-08-11 18:10:52,216 ERROR Received error notification: Event application failed: seqno=1 fragno=0 message=java.sql.SQLException: Statement failed on slave but succeeded on master&lt;br /&gt;Caused by : java.sql.SQLException: Statement failed on slave but succeeded on master&lt;br /&gt;Caused by : Statement failed on slave but succeeded on master&lt;br /&gt;Caused by : Table 't1' already exists&lt;br /&gt;Caused by : Table 't1' already exists&lt;br /&gt;2011-08-11 18:10:54,721 INFO  State changed ONLINE -&gt; OFFLINE:ERROR&lt;br /&gt;2011-08-11 18:10:54,721 WARN  Received irrelevant event for current state: state=OFFLINE:ERROR event=OfflineNotification&lt;br /&gt;&lt;/pre&gt;That's much better. It is not perfect yet, but it will be soon. Right now, it tells me what is wrong without forcing me to go hunting for it amid hundreds of stack trace lines.  Give it a try, using the &lt;a href="http://s3.amazonaws.com/files.continuent.com/builds/nightly/tungsten-2.0-snapshots/index.html"&gt;latest replicator build&lt;/a&gt;. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-7937723470921980252?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/7937723470921980252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=7937723470921980252' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7937723470921980252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7937723470921980252'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/08/usability-improvements-in-tungsten-204.html' title='Usability improvements in Tungsten Replicator 2.0.4'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/_gVfZHGgf5LA/TXO04pRkW0I/AAAAAAAABEE/Ws3-Py7RMdE/s72-c/Tungsten_multi_source_replication.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-3092813482316860588</id><published>2011-08-10T14:25:00.002+02:00</published><updated>2011-08-10T14:26:57.222+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='oreilly'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='percona'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Call for disclosure on MySQL Conference 2012</title><content type='html'>Percona has announced &lt;a href="http://www.mysqlperformanceblog.com/2011/08/09/announcing-percona-live-mysql-conference-and-expo-2012/"&gt;Percona Live MySQL Conference and Expo 2012&lt;/a&gt;. Kudos for their vision and entrepreneurship. I have seen comments praising their commitment to the community and their willingness to filling a void.  I have to dot a few i's and cross some t's on this matter.  &lt;br /&gt;&lt;h3&gt;That was not the only game in town.&lt;/h3&gt;By the end of June, there were strong clues that O'Reilly was not going to organize a conference. The question of who could fill the void started to pop up. The MySQL Council started exploring the options for a community-driven conference to replace the missing one. The general plan was  along the lines of "let's see who is in, and eventually run a conference without the big organizer. If nobody steps up, the IOUG can offer a venue in Las Vegas for an independent MySQL conference". The plan required general consensus among the major players, and therefore we started asking around about availability and participation. Percona did not answer our requests. They delayed the meeting, and in the meantime we continued preparing for the plan B of a conference in Vegas.  Then some of us received a message from Percona, pre-announcing a conference in Santa Clara. No offer to gather a broad participation from other entities. No sign of wanting to do a neutral event, i.e. an event not tied to a single company.  &lt;br /&gt;&lt;h3&gt;Some background&lt;/h3&gt;That was puzzling, because I recall vividly how Baron Schwartz and Peter Zaitzev advocated strongly in favor of an independent conference, not so long ago:  &lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;The conference is organized and owned by MySQL, not the users. It isn’t a community event. It isn’t about you and me first and foremost. It’s about a company trying to successfully build a business, and other companies paying to be sponsors and show their products in the expo hall.&lt;/i&gt;  &lt;br /&gt;Baron Schwartz, &lt;a href="http://www.xaprb.com/blog/2008/04/23/like-it-or-not-it-is-the-mysql-conference-and-expo/"&gt;April 23, 2008&lt;/a&gt;. &lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;I would like to see the conference which is focused on the product users interests rather than business interests of any particular company (or personal interests of small group of people), I would like it to be affordable so more people can attend and I’d like to see it open so everyone is invited to contribute and process is as open as possible.&lt;/i&gt; &lt;br /&gt;Peter Zaitzev, &lt;a href="http://www.mysqlperformanceblog.com/2008/04/23/conference-for-mysql-users/"&gt;April 23, 2008&lt;/a&gt;.&lt;/blockquote&gt;&lt;h3&gt;A call to disclosure&lt;/h3&gt;I understand the business motivation to organize a conference with your company name in the title, while at the same time leveraging the wide MySQL community. However, if I have to judge by the organization of previous Percona Live events, I don't see any of the benefits that were advocated three years ago.  I see a business conference that is inspired to the same principles that Percona was criticizing in 2008.   What is it then? If it is supposed to be a community conference, let's call it "MySQL Conference" and ask for broad participation. There are plenty of people in the community who are willing to help and make the event a success, not only for the benefit of Percona, but for the global benefit of everyone in the ecosystem, including Oracle, the IOUG, and every company with a business related to MySQL.  If it is not a community conference, let's state it clearly, so that people can set their expectations accordingly.  &lt;br /&gt;&lt;h3&gt;Unintended consequences&lt;/h3&gt;Someone may think it's a good thing to have a MySQL conference without Oracle participation but I am sure most will agree that it is not desirable. Much as I admire Percona's technical merits, if I go to the conference I want to hear from a wide range of participants. Specifically, I would like to know what's in the pipeline, and I want to hear that from the engineers in the MySQL team, i.e. from Oracle.   I doubt that Oracle would send engineers and VPs to talk to a conference that is named after a competitor, and that may be true for other entities, which I (and many others) would like to hear from.  &lt;br /&gt;&lt;h3&gt;In short&lt;/h3&gt;Is this the conference of Baron's and Peter's earlier dreams or is it the fulfillment of their current business strategy? &lt;br /&gt;Please, let the community know.  &lt;br /&gt;&lt;h3&gt;Disclaimer&lt;/h3&gt;The opinions in this post are my own. My employer does not censor my writings and gives me full freedom of expression, but my opinion does not necessarily match that of my company. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-3092813482316860588?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/3092813482316860588/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=3092813482316860588' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3092813482316860588'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3092813482316860588'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/08/call-for-disclosure-on-mysql-conference.html' title='Call for disclosure on MySQL Conference 2012'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-4993255319069027412</id><published>2011-06-22T13:04:00.004+02:00</published><updated>2011-06-23T12:44:47.176+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tricks'/><category scheme='http://www.blogger.com/atom/ns#' term='5.5'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='5.1'/><title type='text'>Less known facts about MySQL user grants</title><content type='html'>Reading &lt;a href="http://code.openark.org/blog/mysql/mysql-security-inconsistencies"&gt;MySQL security: inconsistencies&lt;/a&gt; I remembered a few related experiments that I did several years ago when I was studying for the MySQL certification.  The first fact that came to mind is about the clause "WITH GRANT OPTION", which can only be given on the full set of options, not on a single grant. For example &lt;br /&gt;&lt;pre&gt;GRANT INSERT,DELETE,UPDATE on world.* to myuser identified by 'mypass';&lt;br /&gt;GRANT SELECT on world.* to myuser identified by 'mypass' WITH GRANT OPTION;&lt;br /&gt;show grants for myuser\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;Grants for myuser@%: GRANT USAGE ON *.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4'&lt;br /&gt;*************************** 2. row ***************************&lt;br /&gt;Grants for myuser@%: GRANT SELECT, INSERT, UPDATE, DELETE ON `world`.* TO 'myuser'@'%' WITH GRANT OPTION&lt;br /&gt;&lt;/pre&gt;If you are surprised about the "WITH GRANT OPTION" clause applying to all grants instead of only applying to the SELECT, you forgot to consider how the grants are stored. All the grants for a given user (and a user is the combination of a name and a provenience) are stored in a single record in the mysql.user table. The GRANT OPTION is a column in that record. It is either set or not. You can't assign this option for only one attribute in the same record. It's either all the flagged grants or nothing. If you want to assign the "with grant option" on a single column, you must change either the provenience or the name of the user (thus opening another record). But also this addition may not be enough to reach your goal, as you can see in the next section.   The other fact that came to mind about the "WITH GRANT OPTION" clause is that, in the examples given, it is ineffective. I dare say &lt;i&gt;illusory&lt;/i&gt;.  Let's start. As &lt;i&gt;root&lt;/i&gt; user, we create this user: &lt;br /&gt;&lt;pre&gt;root&amp;gt; grant all on granted.* to grantee identified by 'happyuser' with grant option;&lt;/pre&gt;The &lt;i&gt;granted&lt;/i&gt; database exists, and now we have an user that can modify it, and, we think, delegate some functions to someone else.  &lt;br /&gt;&lt;pre&gt;grantee&amp;gt; grant select on granted.* to delegated identified by 'happy';&lt;br /&gt;ERROR 1410 (42000): You are not allowed to create a user with GRANT&lt;br /&gt;grantee&amp;gt; create user delegated;&lt;br /&gt;ERROR 1227 (42000): Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation&lt;/pre&gt;Right. I can't create a new user, but only transfer my superpowers to someone else. I will ask root to create the user, and then I will give it another try.  &lt;br /&gt;&lt;pre&gt;root&amp;gt;  create user delegated;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;grantee&amp;gt; grant select on granted.* to delegated identified by 'happy';&lt;br /&gt;ERROR 1044 (42000): Access denied for user 'grantee'@'%' to database 'mysql'&lt;br /&gt;&lt;/pre&gt;Ouch! Since the grant tables are in the 'mysql' database, I don't have access. I will ask root to give me access to the mysql 'user' and 'db' tables.  &lt;br /&gt;&lt;pre&gt;root&amp;gt;  grant insert on mysql.user to grantee ;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;root&amp;gt;  grant insert on mysql.db to grantee ;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;grantee&amp;gt; grant select on granted.* to delegated identified by 'happy';&lt;br /&gt;ERROR 1044 (42000): Access denied for user 'grantee'@'%' to database 'mysql'&lt;br /&gt;&lt;/pre&gt;Not good. I tried then to get SELECT,INSERT,UPDATE,DELETE for all the grant tables inside 'mysql'.  Still, I could not exercise my grant options. Finally, the only solution was to get privilegs on the whole mysql database.  &lt;br /&gt;&lt;pre&gt;root&amp;gt; grant insert,select,delete,update on mysql.* to grantee;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;grantee&amp;gt; grant select on granted.* to delegated identified by 'happy';&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;/pre&gt;At last, I can grant something to someone. &lt;br /&gt;But wait! Now that I can modify the 'mysql' database ...perhaps I could ...  &lt;br /&gt;&lt;pre&gt;grantee&amp;gt; update user set Select_priv ='Y',&lt;br /&gt; Insert_priv ='Y', Update_priv ='Y', Delete_priv ='Y',&lt;br /&gt; Create_priv ='Y', Drop_priv ='Y', Reload_priv ='Y',&lt;br /&gt; Shutdown_priv ='Y', Process_priv ='Y', File_priv ='Y',&lt;br /&gt; Grant_priv ='Y', References_priv ='Y', Index_priv ='Y',&lt;br /&gt; Alter_priv ='Y', Show_db_priv ='Y', Super_priv ='Y',&lt;br /&gt; Create_tmp_table_priv ='Y', Lock_tables_priv ='Y', Execute_priv ='Y',&lt;br /&gt; Repl_slave_priv ='Y', Repl_client_priv ='Y', Create_view_priv ='Y',&lt;br /&gt; Show_view_priv ='Y', Create_routine_priv ='Y', Alter_routine_priv ='Y',&lt;br /&gt; Create_user_priv ='Y', Event_priv ='Y', Trigger_priv ='Y',&lt;br /&gt; Create_tablespace_priv ='Y' where user = 'grantee';&lt;br /&gt;&lt;/pre&gt;This does not enhance my current grants, because I don't have the SUPER privilege (yet), but I can wait until the server restarts or until someone issues a 'flush privileges'. An then I will have full access to the server.  Obviously, this situation is not what the DBA had in mind when the user 'grantee' was created.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt; The habit of always seeing the password set as integral part of the GRANT command has made me err on judgment. &lt;br /&gt;As noted in one of the comments, the "grantee" user could have granted privileges to "delegated" without assigning a password. In this case,"grantee" does not need separate grants to the mysql database, which were apparently needed only if you wanted to set the password with the GRANT command. &lt;br /&gt;All the above post is a miscalculation. The additional grants are not needed, provided that you don't include a password clause in your GRANT command.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-4993255319069027412?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/4993255319069027412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=4993255319069027412' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4993255319069027412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4993255319069027412'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/06/less-known-facts-about-mysql-user.html' title='Less known facts about MySQL user grants'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-35169554603522427</id><published>2011-06-20T14:20:00.001+02:00</published><updated>2011-06-20T14:20:28.965+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Introducing the Tungsten-toolbox</title><content type='html'>&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://code.google.com/p/tungsten-toolbox" title="tungsten toolbox white"&gt;&lt;img height="165" title="tungsten toolbox" alt="tungsten toolbox white" border="0" src="http://farm3.static.flickr.com/2775/5852731844_d6286c598b_m.jpg" width="240"/&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt; After the public home for &lt;a href="http://tungsten-replicator.org"&gt;Tungsten Replicator&lt;/a&gt;, we needed another place where to host complementary tools. We discussed the pros and cons of hosting these tools in the same place where we publish Tungsten, but in the end we decided that it's more practical to have a separate project, where we can publish tools related to database replication, no matter if they are dedicated to Tungsten or if they can work with other replication systems.So, here it is. We have now &lt;a href="http://code.google.com/p/tungsten-toolbox"&gt;Tungsten Toolbox&lt;/a&gt;, a site where we will collect our tools and accept contributions from others.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; We have already a few tools that, after being cleaned up, will find their way to this repository. The one that was more or less ready for prime time is the &lt;a href="http://code.google.com/p/tungsten-toolbox/wiki/TungstenSandbox"&gt;Tungsten Sandbox&lt;/a&gt;, a tool that installs more than one Tungsten instance with a backend database in the same host. It is, as you can imagine, based on the &lt;a href="http://mysqlsandbox.net"&gt;MySQL Sandbox&lt;/a&gt; and it works reasonably well.All the tools in this toolbox are released under the New BSD License. What can you expect to see in the near future?We have a few ideas already:&lt;ul&gt;&lt;li&gt;A binary log analyzer&lt;/li&gt;&lt;li&gt;A tool that changes properties on-the-fly&lt;/li&gt;&lt;li&gt;A JSON API for Tungsten&lt;/li&gt;&lt;li&gt;Sandboxes and deployers for complex topologies (multiple masters, fan-in)&lt;/li&gt;&lt;li&gt;Sandboxes and deployers for direct slaves&lt;/li&gt;&lt;li&gt;Deployers for a mix of MySQL native and Tungsten replication&lt;/li&gt;&lt;li&gt;A PostgreSQL sandbox&lt;/li&gt;&lt;/ul&gt;We are, of course, open to contributions. If you have a tool that is useful for database replication and want to release it under a BSD license, feel free to propose it in the &lt;a href="http://groups.google.com/group/tungsten-replicator-discuss"&gt;Google Group discussion on Tungsten Replicator&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-35169554603522427?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/35169554603522427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=35169554603522427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/35169554603522427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/35169554603522427'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/06/introducing-tungsten-toolbox.html' title='Introducing the Tungsten-toolbox'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2775/5852731844_d6286c598b_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-6612499517177694691</id><published>2011-06-14T11:43:00.005+02:00</published><updated>2011-06-14T16:43:32.218+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='forge'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><title type='text'>What happened to MySQL Forge?</title><content type='html'>&lt;i&gt;&lt;b&gt;Update&lt;/b&gt;&lt;br /&gt;Soon after I posted this article, the Forge came back online! Thanks!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forge.mysql.com"&gt;MySQL Forge&lt;/a&gt; has been offline for two days now. (2011-06-14) No sign of acknowledgement of this problem from the MySQL team. What is happening?  For those not well acquainted with MySQL Forge, here are the facts. The MySQL Forge is a site that was intended to contain all community contributions. The reality did not follow the plans very closely, and some sections of the forge ended up with less contents than what should be useful.  However, there are a few sections of the forge that are extremely useful to users: &lt;ul&gt;&lt;li&gt;&lt;b&gt;The Wiki&lt;/b&gt;, which is full of irreplaceable documentation, such as the MySQL internals, description of preview features, slides and recordings of MySQL University, manual of many tools (such as the &lt;a href="http://launchpad.net/randgen"&gt;Random Query Generator&lt;/a&gt;, and more &lt;/li&gt;&lt;li&gt;&lt;b&gt;The worklogs&lt;/b&gt;, or the blueprints for most MySQL features, past, present, and future&lt;/li&gt;&lt;li&gt;&lt;b&gt;The tools/snippets&lt;/b&gt;, which is a collection of community contributed scripts. Not many, but most of them of high quality and quite useful.&lt;/li&gt;&lt;/ul&gt;I know that there was a lot of spam in the forge, but I really hope that it was taken off line on purpose. If its maintenance is a problem, I am sure we can find plenty of volunteers in the community that want to host the wiki and the rest of the useful stuff.  Hello? Anybody there at Oracle/MySQL? Please give us back the forge. Thanks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-6612499517177694691?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/6612499517177694691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=6612499517177694691' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6612499517177694691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6612499517177694691'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/06/what-happened-to-mysql-forge.html' title='What happened to MySQL Forge?'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-4840154523880344039</id><published>2011-06-09T15:54:00.003+02:00</published><updated>2011-10-16T07:15:23.522+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='webinar'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='gpl'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Getting started with Tungsten Replicator and Tungsten Sandbox</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://tungsten-replicator.org/"&gt;&lt;img src="https://lh6.googleusercontent.com/-WauMomvciz0/TfCsuCvt9DI/AAAAAAAABH8/uVWOo06Bho8/Tungsten_favorite_sticker.png" width="300" /&gt;&lt;/a&gt; &lt;/td&gt; &lt;td&gt;We have been busy, at &lt;a href="http://www.continuent.com/"&gt;Continuent&lt;/a&gt;. In addition to our usual work with high performance replication, we have addressed usability issues, since we know that a hard-to-use problem, no matter how powerful, has low adoption. Thus, is with some personal satisfaction that I can announce the release of &lt;a href="http://tungsten-replicator.org/"&gt;Tungsten Replicator 2.0.3&lt;/a&gt;, which comes with several huge improvements in matter of user friendliness.  The new installation procedure is so user friendly, in fact, that I was able to build a sophisticated &lt;a href="http://code.google.com/p/tungsten-replicator/downloads/detail?name=tungsten-sandbox"&gt;tungsten-sandbox&lt;/a&gt; with a 150-line shell script. (The corresponding features for MySQL Sandbox required 4,500 lines of Perl).  &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Enough self celebration, though. Let's get started, as the title of this post suggests, with the practical steps.  &lt;br /&gt;&lt;h3&gt;Requirements&lt;/h3&gt;Before we begin, there are a few requirements to meet.  &lt;br /&gt;&lt;ol&gt;&lt;li&gt;You need to be on a Unix-like operating system. Our main choice is Linux. If you want to test on Mac OSX, it works, but we won't recommend it.&lt;/li&gt;&lt;li&gt;Java JRE must be installed. And it must be the &lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html"&gt;original one&lt;/a&gt;, not the Open JDK. &lt;b&gt;Update: The requirement against OpenJDK has been lifted. It works fine in my tests.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Ruby 1.8 must be installed. This is mainly needed during the installation phase only, but it is required nonetheless.&lt;/li&gt;&lt;li&gt;The user account that will install and run Tungsten must have ssh access to the other hosts involved in the cluster&lt;/li&gt;&lt;li&gt;The above mentioned user must have sudo access. This is only needed if you want to use Tungsten Replicator to run backups that involve root access (like xtrabackup). We may lift this requirement later, but for now you need to enable it, at least during the installation, and remove the access when you are done.&lt;/li&gt;&lt;li&gt;This user must also have read access to MySQL binary logs. Usually you achieve this by making sure that the binary logs are readable by users belonging to the "mysql" group, and by adding such group to your user.&lt;/li&gt;&lt;li&gt;There must be a MySQL users for Tungsten replication. This user must have full access to the database server, with grant option.&lt;/li&gt;&lt;li&gt;The MySQL server must have binary logging enabled.&lt;/li&gt;&lt;li&gt;If you have MySQL native replication running, you must &lt;b&gt;stop it&lt;/b&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Getting the code and install&lt;/h3&gt;The code is released in the &lt;a href="http://code.google.com/p/tungsten-replicator/downloads/list"&gt;downloads section&lt;/a&gt; of Tungsten's home. The current recommended version is 2.0.3, but if you like to be really up to date, we also publish a &lt;a href="http://s3.amazonaws.com/files.continuent.com/builds/nightly/tungsten-2.0-snapshots/index.html"&gt;list of recent builds from our build server&lt;/a&gt;, which you can use to have a go at the replicator. For this simple installation, I will use four servers from our server farm. The servers are named R1, R2, R3, and R4. The first good news of the new installation process is this: &lt;b&gt;you need to install in one server only!&lt;/b&gt;. More details follow.  First off, create a directory where you want to install. Use a &lt;b&gt;non-root&lt;/b&gt; account. Just make sure that it's the same user in all the servers, and that such user can access the directory where you want to install. I am going to call this directory &lt;b&gt;planet&lt;/b&gt;.  &lt;br /&gt;&lt;pre&gt;cd $HOME&lt;br /&gt;for N in 1 2 3 4 ; do ssh r$N mkdir planet ; done&lt;br /&gt;cd planet &lt;br /&gt;wget http://tungsten-replicator.googlecode.com/files/tungsten-replicator-2.0.3.tar.gz&lt;br /&gt;tar -xzf tungsten-replicator-2.0.3.tar.gz&lt;br /&gt;cd tungsten-replicator-2.0.3&lt;br /&gt;&lt;/pre&gt;I have already a MySQL user named &lt;i&gt;tungsten&lt;/i&gt; with password "mypwd" (but it can be anything you like, as long as it has the required privileges). Now we have all the components. If you have read the Tungsten documentation, please &lt;b&gt;ignore the &lt;i&gt;./configure&lt;/i&gt; script&lt;/b&gt;. That is left for compatibility reasons, and will be deprecated soon.  Instead, to install the cluster of our 4 servers, let's do the following: &lt;br /&gt;&lt;pre&gt;export TUNGSTEN_BASE=$HOME/planet&lt;br /&gt;&lt;br /&gt;./tools/tungsten-installer \&lt;br /&gt;    --master-slave \&lt;br /&gt;    --master-host=r1 \&lt;br /&gt;    --datasource-user=tungsten \&lt;br /&gt;    --datasource-password=mypwd \&lt;br /&gt;    --service-name=dragon \&lt;br /&gt;    --home-directory=$TUNGSTEN_BASE \&lt;br /&gt;    --cluster-hosts=r1,r2,r3,r4 \&lt;br /&gt;    --start&lt;br /&gt;&lt;/pre&gt;Some comment on this command: &lt;b&gt;--master-slave&lt;/b&gt; is the installation mode (see below for more info). &lt;b&gt;--service-name&lt;/b&gt; can be anything you want. &lt;b&gt;--home-directory&lt;/b&gt; is where all the installation sub directories will go. &lt;b&gt;--cluster-hosts&lt;/b&gt; is the list of servers you want to install, and finally, &lt;b&gt;--master-host&lt;/b&gt; is the host that will be installed as a master, while all the others will be slaves of that one.  If you have followed the instructions carefully, the installer will bring up the Tungsten cluster without any fuss, Unix style. If you hate silent installations, you can get the full monty by adding some options: &lt;br /&gt;&lt;pre&gt;./tools/tungsten-installer \&lt;br /&gt;    &lt;b&gt;--verbose&lt;/b&gt; \&lt;br /&gt;    --master-slave \&lt;br /&gt;    --master-host=r1 \&lt;br /&gt;    --datasource-user=tungsten \&lt;br /&gt;    --datasource-password=mypwd \&lt;br /&gt;    --service-name=dragon \&lt;br /&gt;    --home-directory=$TUNGSTEN_BASE \&lt;br /&gt;    --cluster-hosts=r1,r2,r3,r4 \&lt;br /&gt;    &lt;b&gt;--start-and-report&lt;/b&gt;&lt;br /&gt;&lt;/pre&gt;If you run the installer in verbose mode, you will see an extremely long list of validation checks that the installed does on your current servers and on the ones that are listed in the --cluster-hosts option. If everything went well, you will find the following directories in $HOME/planet (for all servers in your cluster): &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;configs&lt;/b&gt;, containing the configuration file created by the installer. This file describes your cluster&lt;/li&gt;&lt;li&gt;&lt;b&gt;releases&lt;/b&gt;, containing the Tungsten binaries. &lt;/li&gt;&lt;li&gt;&lt;b&gt;thl&lt;/b&gt;, containing Tungsten's Transaction History Logs. These logs are like MySQL binary logs, but with much more metadata, including a global transaction ID, which is missing in MySQL native replication.&lt;/li&gt;&lt;li&gt;&lt;b&gt;relay&lt;/b&gt;, which should be empty, unless you install in "direct" mode (see below.)&lt;/li&gt;&lt;li&gt;&lt;b&gt;tungsten&lt;/b&gt;, which is a symlink to the Tungsten directory inside &lt;i&gt;releases&lt;/i&gt;.&lt;/li&gt;&lt;/ul&gt;In addition to the above mentioned directories, Tungsten Replicator creates a database for each service. Since we have only one service in this topology, you will find a database named "tungsten_dragon". (If you have called your service "bunny", you will instead find "tungsten_bunny"). Inside this database there is the replication metadata necessary for making the servers fault tolerant. Only a small amount of data  is kept on that database. It's roughly corresponding to what you get from the .info files in MySQL native replication.  To test that the system is OK, let's find our tools. The first one is &lt;b&gt;trepctl&lt;/b&gt;, which, among other things, can give us an overview of the running services. &lt;br /&gt;&lt;pre&gt;cd $HOME/planet&lt;br /&gt;./tungsten/tungsten-replicator/bin/trepctl services&lt;br /&gt;Processing services command...&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: &lt;b&gt;0&lt;/b&gt;&lt;br /&gt;appliedLatency  : 1.152&lt;br /&gt;role            : &lt;b&gt;slave&lt;/b&gt;&lt;br /&gt;serviceName     : dragon&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;Finished services command...&lt;br /&gt;&lt;br /&gt;./tungsten/tungsten-replicator/bin/trepctl &lt;b&gt;-host r1&lt;/b&gt; services&lt;br /&gt;Processing services command...&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: &lt;b&gt;0&lt;/b&gt;&lt;br /&gt;appliedLatency  : 0.936&lt;br /&gt;role            : &lt;b&gt;master&lt;/b&gt;&lt;br /&gt;serviceName     : dragon&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;Finished services command...&lt;br /&gt;&lt;br /&gt;mysql -h r1 -e 'create schema if not exists test'&lt;br /&gt;mysql -h r1 -e 'create table test.t1 (i int)'&lt;br /&gt;&lt;br /&gt;./tungsten/tungsten-replicator/bin/trepctl services&lt;br /&gt;Processing services command...&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: &lt;b&gt;2&lt;/b&gt;&lt;br /&gt;appliedLatency  : 0.155&lt;br /&gt;role            : slave&lt;br /&gt;serviceName     : dragon&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;Finished services command...&lt;br /&gt;&lt;br /&gt;./tungsten/tungsten-replicator/bin/trepctl -host r1 services&lt;br /&gt;Processing services command...&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: &lt;b&gt;2&lt;/b&gt;&lt;br /&gt;appliedLatency  : 0.044&lt;br /&gt;role            : master&lt;br /&gt;serviceName     : dragon&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;Finished services command...&lt;br /&gt;&lt;/pre&gt;After the installation, trepctl reported the last applied sequence number (appliedLastSeqno) as 0. Following the execution of two commands in the master, such number became 2. If you want to know more of what was happening, you can use the &lt;b&gt;thl&lt;/b&gt; command. This corresponds roughly to using mysqlbinlog with MySQL native replication logs.  &lt;br /&gt;&lt;pre&gt;/tungsten/tungsten-replicator/bin/thl -service dragon list |less&lt;br /&gt;SEQ# = 1 / FRAG# = 0 (last frag)&lt;br /&gt;- TIME = 2011-06-09 14:51:23.0&lt;br /&gt;- EVENTID = 000002:0000000000000514;197609&lt;br /&gt;- SOURCEID = qa.r1.continuent.com&lt;br /&gt;- STATUS = COMPLETED(2)&lt;br /&gt;- METADATA = [mysql_server_id=10;service=dragon;shard=test]&lt;br /&gt;- TYPE = com.continuent.tungsten.replicator.event.ReplDBMSEvent&lt;br /&gt;- OPTIONS = [##charset = ISO8859_1, createOrDropDB = , autocommit = 1, sql_auto_is_null = 1, foreign_key_checks = 1, unique_checks = 1, sql_mode = '', character_set_client = 8, collation_connection = 8, collation_server = 8]&lt;br /&gt;- SQL(0) = create schema if not exists test /* ___SERVICE___ = [dragon] */&lt;br /&gt;SEQ# = 2 / FRAG# = 0 (last frag)&lt;br /&gt;- TIME = 2011-06-09 14:51:30.0&lt;br /&gt;- EVENTID = 000002:0000000000000601;197610&lt;br /&gt;- SOURCEID = qa.r1.continuent.com&lt;br /&gt;- STATUS = COMPLETED(2)&lt;br /&gt;- METADATA = [mysql_server_id=10;service=dragon;shard=test]&lt;br /&gt;- TYPE = com.continuent.tungsten.replicator.event.ReplDBMSEvent&lt;br /&gt;- OPTIONS = [##charset = ISO8859_1, autocommit = 1, sql_auto_is_null = 1, foreign_key_checks = 1, unique_checks = 1, sql_mode = '', character_set_client = 8, collation_connection = 8, collation_server = 8]&lt;br /&gt;- SCHEMA = &lt;br /&gt;- SQL(0) = create table test.t1 (i int) /* ___SERVICE___ = [dragon] */&lt;br /&gt;&lt;/pre&gt;Once we are satisfied that replication is working, we can clean up the cluster and try other installation experiments. To clean up a cluster, you need to do the following: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;stop the replicator in all servers&lt;/b&gt;.&lt;br /&gt;&lt;code&gt;for N in 1 2 3 4; do $PWD/tungsten/tungsten-replicator/bin/replicator stop; done&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;remove the thl files&lt;/b&gt; from all servers. &lt;/li&gt;&lt;li&gt;&lt;b&gt;remove the tungsten_SERVICE_NAME database&lt;/b&gt; from all mysql servers&lt;/li&gt;&lt;li&gt;&lt;b&gt;run a "reset master"&lt;/b&gt; in the master database&lt;/li&gt;&lt;li&gt;&lt;b&gt;remove the directories created by the installer&lt;/b&gt; in all servers&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Installation types&lt;/h3&gt;The procedure described above was, until a few months ago, the only thing you could do with Tungsten. Now you can broaden your horizons with a wider range of possibilities.  &lt;br /&gt;&lt;img src="https://lh5.googleusercontent.com/-jgCZbwwB4WE/TfC6Ksv2LiI/AAAAAAAABIQ/Ygpazw8EvEQ/s800/master_slave.png" width="500" /&gt;  &lt;br /&gt;Master/slave is of course the main option, and it's the one that you have seen in the previous section. This method gives you the full set of Tungsten features and performance. It is the recommended method for production use and for benchmarking. In this scenario, the Tungsten replicator on the master will extract transactions from the binary log, transfer them to the THL, and share it with the slaves. The slaves will read from the THL and apply the transactions to the database. There are a few steps more in between, but for the sake of brevity I will skip them You can have a look at &lt;a href="http://scale-out-blog.blogspot.com/"&gt;Robert Hodges&lt;/a&gt; blog for more info.  &lt;img src="https://lh5.googleusercontent.com/-dhH-sPprwrw/TfC6L_F5RDI/AAAAAAAABIY/UwtVngp962Y/s800/slave_direct.png" width="500" /&gt;  &lt;br /&gt;Slave "direct" is the alternative that you can use in production, and it's been designed to satisfy users who only want some particular benefits on the slave side, and don't care about global transaction IDs. If you are looking at parallel apply, this is probably a setup that you want to try.  In this scenario, there is no replicator on the master. The slave pulls data remotely from the binary logs, copies them locally, and extracts data to the THL.  Here's an example of how to start a slave-direct system: &lt;br /&gt;&lt;pre&gt;./tools/tungsten-installer \&lt;br /&gt;    --direct \&lt;br /&gt;    --master-host=r1 \&lt;br /&gt;    --slave-host=r4 \&lt;br /&gt;    --master-user=tungsten \&lt;br /&gt;    --slave-user=tungsten \&lt;br /&gt;    --master-password=secret \&lt;br /&gt;    --slave-password=secret \&lt;br /&gt;    --service-name=Castor \&lt;br /&gt;    --thl-port=21124 \&lt;br /&gt;    --rmi-port=10104 \&lt;br /&gt;    --channels=5 \&lt;br /&gt;    --home-directory=$TUNGSTEN_BASE \&lt;br /&gt;    --start-and-report&lt;br /&gt;&lt;/pre&gt;&lt;img src="https://lh4.googleusercontent.com/-rHIfADez_jI/TfC6JQSSP8I/AAAAAAAABIM/7TtIX9XNAWw/s800/master_slave_sandbox.png" width="500" /&gt;  &lt;br /&gt;If your purpose is testing Tungsten, probably the Tungsten Sandbox is what you should try. This system is based on &lt;a href="http://mysqlsandbox.net/"&gt;MySQL Sandbox&lt;/a&gt;, a framework that lets you install more than one MySQL server in the same host. Building on top of MySQL Sandbox, and leveraging the new flexibility in Tungsten installer, &lt;a href="http://code.google.com/p/tungsten-replicator/downloads/detail?name=tungsten-sandbox"&gt;tungsten-sandbox&lt;/a&gt; allows you to build a master/slave system inside a single host.  Let's give it a try. You need to have MySQL Sandbox installed, and at least one MySQL tarball expanded under $HOME/opt/mysql/X.X.XX (where X.X.XX is the MySQL version, such as 5.5.12).  &lt;br /&gt;&lt;pre&gt;cd $HOME/planet&lt;br /&gt;mkdir sb&lt;br /&gt;cd tungsten-replicator-2.0.3&lt;br /&gt;wget http://tungsten-replicator.googlecode.com/files/tungsten-sandbox&lt;br /&gt;./tungsten-sandbox -h&lt;br /&gt;USAGE: ./tungsten-sandbox [flags] args&lt;br /&gt;flags:&lt;br /&gt;  -n,--nodes:  how many nodes to install (default: 3)&lt;br /&gt;  -m,--mysql_version:  which MySQL version to use (default: '5.1.56')&lt;br /&gt;  -t,--tungsten_base:  where to install the sandbox (default: '/home/tungsten/tsb2')&lt;br /&gt;  -d,--group_dir:  sandbox group directory name (default: 'tr_dbs')&lt;br /&gt;  -s,--service:  how the service is named (default: 'tsandbox')&lt;br /&gt;  -P,--base_port:  port base for MySQL sandbox nodes (default: 710)&lt;br /&gt;  -l,--thl_port:  port for the THL service (default: 1211)&lt;br /&gt;  -r,--rmi_port:  port for the RMI service (default: 1010)&lt;br /&gt;  -v,--[no]version:  show Tungsten sandbox version (default: false)&lt;br /&gt;  -h,--[no]help:  show Tungsten sandbox help (default: false)&lt;br /&gt;&lt;/pre&gt;In my server, I have already expanded MySQL 5.5.10, and I want to install inside $HOME/tsb. So, here is what I do:  &lt;br /&gt;&lt;pre&gt;./tungsten-sandbox -m 5.5.10 -t ~/tsb&lt;br /&gt;&lt;/pre&gt;This command installs three instances of MySQL under $HOME/sandboxes and three of Tungsten under $HOME/tsb. Inside this directory, in addition to the running instances, we find some more goodies:  &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;clear_all send_kill_all  start_all  status_all  stop_all use_all&lt;/b&gt; : symlinks to the corresponding commands in MySQL sandbox &lt;/li&gt;&lt;li&gt;&lt;b&gt;db1  db2  db3&lt;/b&gt;: these are the tungsten instances.&lt;/li&gt;&lt;li&gt;&lt;b&gt;n1  n2  n3&lt;/b&gt;: quick links to access each MySQL node&lt;/li&gt;&lt;li&gt;&lt;b&gt;replicator_all   trepctl_all&lt;/b&gt;: utilities that run "replicator" or "trepctl" for each node with the arguments provided on the command line&lt;/li&gt;&lt;/ul&gt;Additionally, there are a few scripts inside each Tungsten instance in the sandbox: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;trepctl&lt;/b&gt;: a link to the deep down trepctl&lt;/li&gt;&lt;li&gt;&lt;b&gt;thl&lt;/b&gt;: a link to the thl utility&lt;/li&gt;&lt;li&gt;&lt;b&gt;show_log&lt;/b&gt;: a quick way of showing the replicator log&lt;/li&gt;&lt;/ul&gt;Since this is a tool for testing, removing it is going to be easy. &lt;br /&gt;&lt;pre&gt;~/tsb/replicator_all stop&lt;br /&gt;~/tsb/clear_all&lt;br /&gt;rm -rf ~/tsb/*&lt;br /&gt;&lt;/pre&gt;&lt;img src="https://lh3.googleusercontent.com/-d-bOBRQAd68/TfC6KqEUAbI/AAAAAAAABIU/5Y52k2jXTmA/s800/slave_direct_sandbox.png" width="500" /&gt;  &lt;br /&gt;A final method of installing is a sandbox with ths slave-direct method. There is no dedicated script for this method, but thanks to the new installer, you can get the job done quite easily: &lt;br /&gt;&lt;pre&gt;export NODE_OPTIONS='-c innodb_flush_log_at_trx_commit=2 -c max_allowed_packet=48M'&lt;br /&gt;make_multiple_sandbox --group_directory=tr_dbs --sandbox_base_port=7100 5.5.10&lt;br /&gt;&lt;br /&gt;TUNGSTEN_BASE=$HOME/tinstall/tsb/&lt;br /&gt;./tools/tungsten-installer \&lt;br /&gt;    --direct \&lt;br /&gt;    --master-host=127.0.0.1 \&lt;br /&gt;    --master-port=7101 \&lt;br /&gt;    --slave-host=db2 \&lt;br /&gt;    --slave-port=7102 \&lt;br /&gt;    --master-user=root \&lt;br /&gt;    --slave-user=root \&lt;br /&gt;    --master-password=msandbox \&lt;br /&gt;    --slave-password=msandbox \&lt;br /&gt;    --master-log-directory=$HOME/sandboxes/tr_dbs/node1/data \&lt;br /&gt;    --service-name=Castor \&lt;br /&gt;    --thl-port=12112 \&lt;br /&gt;    --channels=5 \&lt;br /&gt;    --rmi-port=20000 \&lt;br /&gt;    --home-directory=$TUNGSTEN_BASE \&lt;br /&gt;&lt;br /&gt;./tools/tungsten-installer \&lt;br /&gt;    --direct \&lt;br /&gt;    --master-host=127.0.0.1 \&lt;br /&gt;    --master-port=7101 \&lt;br /&gt;    --slave-host=db3 \&lt;br /&gt;    --slave-port=7103 \&lt;br /&gt;    --master-user=root \&lt;br /&gt;    --slave-user=root \&lt;br /&gt;    --master-password=msandbox \&lt;br /&gt;    --slave-password=msandbox \&lt;br /&gt;    --master-log-directory=$HOME/sandboxes/tr_dbs/node1/data \&lt;br /&gt;    --service-name=Pollux \&lt;br /&gt;    --thl-port=22112 \&lt;br /&gt;    --channels=1 \&lt;br /&gt;    --rmi-port=20000 \&lt;br /&gt;    --home-directory=$TUNGSTEN_BASE \&lt;br /&gt;    --relay-directory=$TUNGSTEN_BASE/relay --start-and-report&lt;br /&gt;&lt;/pre&gt;This script creates two services (Castor and Pollux), with only one instance of Tungsten replicator, with all the servers (MySQL and Tungsten ones) in the same host.  &lt;br /&gt;&lt;h3&gt;Conclusions&lt;/h3&gt;There should be much more to say, but I will leave it for the coming days. In the meantime, I encourage everyone to try the new Tungsten and submit &lt;a href="http://code.google.com/p/tungsten-replicator/issues/list"&gt;bug reports&lt;/a&gt; when things don't work as expected. As always, happy hacking!&lt;br /&gt;P.S. Today at 10am PT there is a &lt;a href="http://www.continuent.com/news/webinars"&gt;webinar&lt;/a&gt; on this very topic!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-4840154523880344039?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/4840154523880344039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=4840154523880344039' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4840154523880344039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4840154523880344039'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/06/getting-started-with-tungsten.html' title='Getting started with Tungsten Replicator and Tungsten Sandbox'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/-WauMomvciz0/TfCsuCvt9DI/AAAAAAAABH8/uVWOo06Bho8/s72-c/Tungsten_favorite_sticker.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-3254880046070851307</id><published>2011-05-17T23:00:00.002+02:00</published><updated>2011-05-17T23:01:45.022+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='5.5'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmarks'/><category scheme='http://www.blogger.com/atom/ns#' term='semisynch'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>The price of safe data - Benchmarking semi synchronous replication</title><content type='html'>Some time ago I wrote about &lt;a href="http://datacharmer.blogspot.com/2010/11/testing-mysql-55-semi-synchronous.html"&gt;MySQL 5.5 semi-synchronous replication&lt;/a&gt;. Since then, I have wanted to benchmark the overhead of semi-synchronous replication with a decent server.  Now the occasion presented itself, thanks to some related business that I had to benchmark, and thus I did a few simple runs with and without semi-synchronous replication enabled, to see the impact of this feature on performance. If you haven't read the article on semi-synchronous replication, the bottom line is that, with this feature enabled, the master waits until at least one slave has acknowledged receipt for the data before returning a positive result to the client. This means that for each commit there are two network calls between master and slave. My gut feeling was that this feature would be costly in terms of query response time, although I was not prepared to such a big impact as I found out in my test.  I needed a substantial set of data, and I got it by exporting the employees table from the &lt;a href="http://launchpad.net/test-db"&gt;employees test database&lt;/a&gt;, using one &lt;i&gt;INSERT&lt;/i&gt; per record. Thus, I had about 300,000 records, which are a fair amount for this kind of test. Had I sent the records in a big multiple insert chunk of 10,000 records each, I would have had only 30 commits, which would not have been easy to measure. So, here goes.  &lt;br /&gt;&lt;br /&gt;&lt;b&gt;regular replication&lt;/b&gt; &lt;br /&gt;&lt;pre&gt;$ time mysql &amp;lt; employees.sql &lt;br /&gt;&lt;br /&gt;real &lt;b&gt;0m27.997s&lt;/b&gt;&lt;br /&gt;user 0m1.394s&lt;br /&gt;sys 0m1.046s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;semi-synchronous replication&lt;/b&gt; &lt;br /&gt;&lt;pre&gt;$ time mysql &amp;lt; employees.sql &lt;br /&gt;real &lt;b&gt;1m24.277s&lt;/b&gt;&lt;br /&gt;user 0m3.842s&lt;br /&gt;sys 0m6.270s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Semi-synchronous replication was three times slower than regular replication.  The test was taken using one master in one host and one slave in two more hosts. The measurements were the same if I had only one or both slaves enabled. Using row-based replication instead of statement-based did not make any substantial impact.  Now my question is: who would be prepared to accept such a performance impact for the sake of more data safety? Data is important, but response time to customers is also important. Your mileage may vary. I know many customers who would think twice before accepting this onerous trade off.  I am curious to know what experience others have had with this feature, and how much performance they are willing to sacrifice for safety.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-3254880046070851307?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/3254880046070851307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=3254880046070851307' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3254880046070851307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3254880046070851307'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/05/price-of-safe-data-benchmarking-semi.html' title='The price of safe data - Benchmarking semi synchronous replication'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-8406849546540963864</id><published>2011-05-06T11:10:00.004+02:00</published><updated>2011-05-06T12:00:51.516+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='sardinia'/><category scheme='http://www.blogger.com/atom/ns#' term='opendatabasecamp'/><category scheme='http://www.blogger.com/atom/ns#' term='pula'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Open Database Camp 2011 opens today!</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://opendbcamp.org/"&gt;&lt;img alt="Open Database Camp 2011" border="0" src="http://lh4.ggpht.com/_gVfZHGgf5LA/TSTzfrsx8_I/AAAAAAAABAg/XRCbqqZEYPM/open_database_sardinia.png" title="Open Database Camp 2011" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;The &lt;a href="http://opendbcamp.org/"&gt;Open Database Camp 2011&lt;/a&gt; opens today with the &lt;a href="http://opensqlcamp.org/Welcome_Party"&gt;Welcome Party&lt;/a&gt;, starting today at 7pm CEST. The party (with good Italian food and drinks) is open to all the ones who have registered in the &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/AttendeeList"&gt;Attendees list&lt;/a&gt;.&lt;br /&gt;By car you have to reach Pula, take Via Nora (Nora Street), than Via Sant'Efisio (Sant'Efisio Street), until the end, directly to the party location.&lt;br /&gt;Organisers will also make a bus available on Friday 6 May, leaving from Pula Hotels (Nora Club Hotel - Villa Madau - Baia Di Nora - Is Molas - Marin Hotel - Is Morus Hotel) around 18:30 and reaching Nora. From Nora back to Pula Hotels a bus will leave around 21:00 and 22:00. &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The conference itself will start on Saturday, May 7th, at 9am. Travel arrangements to reach the venue are listed in the conference wiki (&lt;a href="http://opensqlcamp.org/Events/Sardinia2011/#Travel"&gt;wiki: Travel&lt;/a&gt;). &lt;br /&gt;There will be a bus collecting participants from the hotels at 8:30am and the same bus from the conference venue (Sardegna Ricerche) back to the hotel in the evening.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Sessions&lt;/h3&gt;Open Database camp is an Un-conference. As with the previous editions, the schedule will be decided on the spot, on Saturday. You can list your intended sessions and your wishes in the &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/Sessions"&gt;Sessions&lt;/a&gt; page.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Logistics&lt;/h3&gt;You will need an ID for your wifi access. (Sorry, it's a law requirement)&lt;sup&gt;(*)&lt;/sup&gt;. If you want your username and password, you should collect it at the reception as soon as possible.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Customized meetings&lt;/h3&gt;There will be room for 1:1 meetings between attendees, if you like to do so. You will find a board with the names of all attendees and their affiliation, and you can easily schedule a meeting with them. &lt;br /&gt;&lt;br /&gt;&lt;small&gt;&lt;sup&gt;(*)&lt;/sup&gt; The law has expired but after having put the fear of the state into every internet provider, the lawmakers have not said how the new regulations should be applied. Regretfully, we have still to live with the old rules. &lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-8406849546540963864?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/8406849546540963864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=8406849546540963864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8406849546540963864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8406849546540963864'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/05/open-database-camp-2011-opens-today.html' title='Open Database Camp 2011 opens today!'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_gVfZHGgf5LA/TSTzfrsx8_I/AAAAAAAABAg/XRCbqqZEYPM/s72-c/open_database_sardinia.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-6252212719994234846</id><published>2011-05-02T23:40:00.001+02:00</published><updated>2011-05-02T23:43:55.996+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='linas virbalas'/><category scheme='http://www.blogger.com/atom/ns#' term='mongodb'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Introducing the Flying Clusters, and more than MySQL replication</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://flyingclusters.blogspot.com/"&gt;&lt;img alt="Flying Clusters" border="0" src="https://lh6.googleusercontent.com/_gVfZHGgf5LA/Tb8hTeIdZnI/AAAAAAAABHc/4YDoam-NhxY/Flying%20DB.png" title="Flying Clusters" width="200" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;My Colleague &lt;a href="http://www.blogger.com/profile/18254506169133583586"&gt;Linas Virbalas&lt;/a&gt; has just crossed the boundary between real and virtual and has started a blog, titled &lt;a href="http://flyingclusters.blogspot.com/"&gt;Flying Clusters&lt;/a&gt;.&lt;br /&gt;Linas is a gifted developer who is taking care of the special projects. One of such projects is replication between MySQL and PostgreSQL, which works quite well.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Another project, which has just started, is about providing PostgreSQL with &lt;a href="http://flyingclusters.blogspot.com/2011/05/advanced-logical-replication-for.html"&gt;Advanced Logical Replication&lt;/a&gt; using Tungsten replicator. As you probably know, recent versions of PostgreSQL can do physical replication, which has its pros and cons. With this project, PostgreSQL users can also have the choice of using logical replication. Not only that: since Tungsten Replicator already supports MySQL, cross-DBMS replication clusters are not far away.&lt;br /&gt;We are also more ambitious, and we are exploring ways of replicating to NoSQL entities. We will start with MongoDB at a dedicated &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/Sessions#SQL_to_NoSQL_Replication_Hackathon_-_Robert_Hodges"&gt;SQL to NoSQL Replication Hackathon&lt;/a&gt;, where we will attempt the creation of n applier for MongoDB during the &lt;a href="http://opendbcamp.org"&gt;Open Database Camp &lt;/a&gt; conference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-6252212719994234846?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/6252212719994234846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=6252212719994234846' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6252212719994234846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6252212719994234846'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/05/introducing-flying-clusters-and-more.html' title='Introducing the Flying Clusters, and more than MySQL replication'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/_gVfZHGgf5LA/Tb8hTeIdZnI/AAAAAAAABHc/4YDoam-NhxY/s72-c/Flying%20DB.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5268600327698332905</id><published>2011-04-28T08:34:00.001+02:00</published><updated>2011-04-28T08:36:27.230+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Replication : different points of view</title><content type='html'>The following quotes are the first sentences in the &lt;i&gt;replication&lt;/i&gt; chapter of two similar books. Both are admin cookbooks. One is for PostgreSQL, one for MySQL.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;Replication isn't magic, though it can be pretty cool. It's even cooler when it works, and that's what this chapter is all about.&lt;br /&gt;Replication requires understanding, effort, and patience. There are a significant number of points to get right. My emphasis here is on providing simple approaches to get you started, and some clear best practices on operational robustness&lt;/i&gt;&lt;/blockquote&gt;&lt;a href="https://www.packtpub.com/postgresql-9-admin-cookbook/book"&gt;PostgreSQL 9 Admin Cookbook&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;Replication is an interesting feature of MySQL that can be used for a variety of purposes. It can help to balance server load across multiple machines, ease backups, provide a workaround for the lack of fulltext search capabilities in InnoDB, and much more.&lt;/i&gt;&lt;/blockquote&gt;&lt;a href="http://www.packtpub.com/mysql-admin-cookbook/book"&gt;MySQL Admin Cookbook&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The PostgreSQL quote warns of a dangerous, difficult, and unexplored path, while the MySQL one is the almost bored remark of someone whose biggest problem is to list how many good things you can do. I guess that being exposed to a given technology for longer time changes one's perception.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5268600327698332905?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5268600327698332905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5268600327698332905' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5268600327698332905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5268600327698332905'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/04/replication-different-points-of-view.html' title='Replication : different points of view'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-2182445375568480859</id><published>2011-04-27T13:24:00.000+02:00</published><updated>2011-04-27T13:24:03.235+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='opensqlcamp'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='cassandra'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='opendatabasecamp'/><category scheme='http://www.blogger.com/atom/ns#' term='mongodb'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Open Database camp 2011 - Travel logistics, and don't forget the party</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://opendbcamp.org/"&gt;&lt;img alt="" border="0" src="http://lh5.googleusercontent.com/_gVfZHGgf5LA/TbfzwrXvTDI/AAAAAAAABHQ/IwIdIJ0hE-A/opendbcamp_logistics.png" title="open database camp - logistics" width="200" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;The &lt;a href="http://opendbcamp.org/"&gt;Open Database Camp 2011&lt;/a&gt; is near. In 9 days, the &lt;a href="http://opensqlcamp.org/Welcome_Party"&gt;welcome party&lt;/a&gt; starts, and then the conference itself gets going.&lt;br /&gt;If you are coming earlier than Friday, May 6th, you can either use &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/#Travel"&gt;public transportation&lt;/a&gt; or book a private seat with a volunteer in the &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/ArrivalsDepartures"&gt;car pooling&lt;/a&gt; page. Please help the organizers: post your arrival and departure dates and times, so we may be able to help you even outside the official conference days.&lt;br /&gt;About the conference itself, as everyone should know, it's a un-conference, where the talks will be decided on the spot. But you can book ideas and topics in the &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/Sessions"&gt;sessions &lt;/a&gt; page. &lt;br /&gt;Since we will have many participants from Italy, there will be dedicated sessions in Italian in addition to the ones in English, which is the official language of the conference.  &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-2182445375568480859?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/2182445375568480859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=2182445375568480859' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2182445375568480859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2182445375568480859'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/04/open-database-camp-2011-travel.html' title='Open Database camp 2011 - Travel logistics, and don&apos;t forget the party'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.googleusercontent.com/_gVfZHGgf5LA/TbfzwrXvTDI/AAAAAAAABHQ/IwIdIJ0hE-A/s72-c/opendbcamp_logistics.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-7503060295546583544</id><published>2011-04-17T23:24:00.003+02:00</published><updated>2011-04-18T08:08:19.068+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='5.6'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Replication metadata in MySQL 5.6.2</title><content type='html'>&lt;h3&gt;The default storage engine is InnoDB, or is it not?&lt;/h3&gt;When MySQL 5.5 went GA, the biggest piece of news was that the default storage engine is now InnoDB. Good news, and hope for a better future, as InnoDB is the most reliable storage engine available for MySQL.&lt;br /&gt;&lt;br /&gt;Therefore the expectation is that MySQL 5.6 follows in its steps, and we should see less and less of MyISAM in the database.&lt;br /&gt;The privileges tables, however, are still MyISAM. I was not really expecting to see them disappear so quickly, as I have seen how much work it has been for Drizzle to get rid of them, and even them had to keep MyISAM alive for temporary tables.&lt;br /&gt;However, I was surprised to see that the new tables for replication metadata, the ones that replace the files master.info and relay_log.info are MyISAM by default.&lt;br /&gt;The &lt;a href="http://dev.mysql.com/doc/refman/5.6/en/mysql-nutshell.html"&gt;manual&lt;/a&gt; says:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;In order for replication to be crash-safe, the slave_master_info and slave_relay_log_info tables must each use a transactional storage engine. By default, both of these tables use MyISAM; this means that, prior to starting replication, you must change both of these tables to use a transaction storage engine if you wish for replication to be crash-safe. You can do this by means of the appropriate ALTER TABLE ... ENGINE=... statements. You should not attempt to change the storage engine used by either of these tables while replication is actually running. &lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;The funny thing is that the manual does not mention InnoDB explicitly, as if there were many transactional engines coming with the official MySQL.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Tables instead of files.&lt;/h3&gt;Anyway, I went ahead and tried the new metadata features. In short, the new version allows you to store the data that once were in master.info and relay_log.info in two tables with similar names, located under the &lt;i&gt;mysql&lt;/i&gt; schema.&lt;br /&gt;&lt;br /&gt;First of all, I changed the storage engine, as suggested by the docs. Actually, the docs are still a bit scarce about this feature. The best instructions are the ones found in &lt;a href="http://mysqlmusings.blogspot.com/2011/04/crash-safe-replication.html"&gt;Mats Kindahl&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;# in the slave&lt;br /&gt;ALTER TABLE mysql.slave_master_info ENGINE = InnoDB;&lt;br /&gt;ALTER TABLE mysql.slave_relay_log_info ENGINE = InnoDB;&lt;br /&gt;&lt;br /&gt;# in the slave configuration file&lt;br /&gt;relay-log-info-repository=TABLE&lt;br /&gt;master-info-repository=TABLE&lt;br /&gt;&lt;/pre&gt;After this operation, I initialized the two slaves, one of which has the new table info, and the other one has still the old files info, for comparison.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# slave 1 (with table info)&lt;br /&gt;show slave status\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;               Slave_IO_State: Waiting for master to send event&lt;br /&gt;                  Master_Host: 127.0.0.1&lt;br /&gt;                  Master_User: rsandbox&lt;br /&gt;                  Master_Port: 12027&lt;br /&gt;                Connect_Retry: 60&lt;br /&gt;              Master_Log_File: mysql-bin.000001&lt;br /&gt;          Read_Master_Log_Pos: 114&lt;br /&gt;               Relay_Log_File: mysql_sandbox12028-relay-bin.000002&lt;br /&gt;                Relay_Log_Pos: 267&lt;br /&gt;        Relay_Master_Log_File: mysql-bin.000001&lt;br /&gt;             Slave_IO_Running: Yes&lt;br /&gt;            Slave_SQL_Running: Yes&lt;br /&gt;[...]&lt;br /&gt;&lt;br /&gt;select * from slave_master_info\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;              Master_id: 101&lt;br /&gt;        Number_of_lines: 20&lt;br /&gt;        Master_log_name: &lt;br /&gt;         Master_log_pos: 4&lt;br /&gt;                   Host: &lt;br /&gt;              User_name: &lt;br /&gt;          User_password: &lt;br /&gt;                   Port: 3306&lt;br /&gt;          Connect_retry: 60&lt;br /&gt;            Enabled_ssl: 0&lt;br /&gt;                 Ssl_ca: &lt;br /&gt;             Ssl_capath: &lt;br /&gt;               Ssl_cert: &lt;br /&gt;             Ssl_cipher: &lt;br /&gt;                Ssl_key: &lt;br /&gt;Ssl_verify_servert_cert: 0&lt;br /&gt;              Heartbeat: 1800&lt;br /&gt;                   Bind: &lt;br /&gt;     Ignored_server_ids: 0&lt;br /&gt;                   Uuid: &lt;br /&gt;            Retry_count: 86400&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Slave 2&lt;br /&gt;cat node2/data/master.info &lt;br /&gt;20&lt;br /&gt;mysql-bin.000001&lt;br /&gt;114&lt;br /&gt;127.0.0.1&lt;br /&gt;rsandbox&lt;br /&gt;rsandbox&lt;br /&gt;12027&lt;br /&gt;60&lt;br /&gt;0&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;0&lt;br /&gt;1800.000&lt;br /&gt;&lt;br /&gt;0&lt;br /&gt;6cb60e24-68e7-11e0-9eec-6c626da07446&lt;br /&gt;86400&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hmmm. Not good. Definitely not good.&lt;br /&gt;Now, according to Mats article, the slave_master_info table is updated every time a slave starts. But this is not the case.&lt;br /&gt;Apparently, you need to restart it at least once more, to get an update.&lt;br /&gt;&lt;pre&gt;# slave 1&lt;br /&gt;stop slave; &lt;br /&gt;start slave;&lt;br /&gt;select * from slave_master_info\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;              Master_id: 101&lt;br /&gt;        Number_of_lines: 20&lt;br /&gt;        Master_log_name: mysql-bin.000001&lt;br /&gt;         Master_log_pos: 114&lt;br /&gt;                   Host: 127.0.0.1&lt;br /&gt;              User_name: rsandbox&lt;br /&gt;          User_password: rsandbox&lt;br /&gt;                   Port: 12027&lt;br /&gt;          Connect_retry: 60&lt;br /&gt;            Enabled_ssl: 0&lt;br /&gt;                 Ssl_ca: &lt;br /&gt;             Ssl_capath: &lt;br /&gt;               Ssl_cert: &lt;br /&gt;             Ssl_cipher: &lt;br /&gt;                Ssl_key: &lt;br /&gt;Ssl_verify_servert_cert: 0&lt;br /&gt;              Heartbeat: 1800&lt;br /&gt;                   Bind: &lt;br /&gt;     Ignored_server_ids: 0&lt;br /&gt;                   Uuid: 6cb60e24-68e7-11e0-9eec-6c626da07446&lt;br /&gt;            Retry_count: 86400&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;This lack of update is the default by design. The reasoning is that if you update the table at every transaction, you are slowing down replication beyond acceptable levels. However, it must be noted that the update of the table is way less than the updates of the file. &lt;br /&gt;&lt;br /&gt;You can force the slave_master_info and slave_relay_log_info tables to update at every transaction, by setting &lt;i&gt;sync_master_info&lt;/i&gt; and &lt;i&gt;sync_relay_log_info&lt;/i&gt;. Indeed, with this addition, the table is updated at every transaction.&lt;br /&gt;Therefore the choice is between crash unsafe and fast (with the *.info files) and crash safe and very slow (with the tables).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Usability issues&lt;/h3&gt;&lt;br /&gt;Let's mention the good news first. This addition is very welcome, because it allows monitoring tools to be implemented directly in SQL. The main difficulty about this problem is that the only metadata available until MySQL 5.5 is "SHOW SLAVE STATUS", which has no related Information_Schema or Performance_Schema table. Thus, getting the status values into a SQL variables is not feasible without external tools. This metadata is no replacement for SHOW SLAVE STATUS (that &lt;a href="http://forge.mysql.com/worklog/task.php?id=3656"&gt;worklog&lt;/a&gt; is still struggling with a slow implementation) but there is enough overlapping that a simple monitoring tool could be created with SQL, stored routines and the event scheduler.&lt;br /&gt;&lt;br /&gt;Now, for the bad news:&lt;br /&gt;This implementation leaves me baffled for several reasons. &lt;br /&gt;The lack of updates by default is the biggest concern. There is no option of automatic updates every second, same as synch_binlog. It's all or nothing.&lt;br /&gt;&lt;br /&gt;The choice of implementation is not pleasant either. Users would expect the table-based recording to mimic the behavior of the file-based recording, i.e. when replication is started, the table is created, and after a "reset slave' the table is removed. But this does not happen. The table is truncated, and if you remove it, it won't be created when you restart replication.&lt;br /&gt;&lt;br /&gt;What's worse, this table can't be dumped with locks. MySQL complains if you attempt to do that.&lt;br /&gt;&lt;pre&gt;./s1 -e 'stop slave'&lt;br /&gt;&lt;br /&gt;mysqldump mysql slave_master_info&lt;br /&gt;-- MySQL dump 10.13  Distrib 5.6.2-m5, for linux2.6 (x86_64)&lt;br /&gt;--&lt;br /&gt;-- Host: localhost    Database: mysql&lt;br /&gt;-- ------------------------------------------------------&lt;br /&gt;-- Server version 5.6.2-m5-log&lt;br /&gt;&lt;br /&gt;/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;&lt;br /&gt;/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;&lt;br /&gt;/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;&lt;br /&gt;/*!40101 SET NAMES utf8 */;&lt;br /&gt;/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;&lt;br /&gt;/*!40103 SET TIME_ZONE='+00:00' */;&lt;br /&gt;/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;&lt;br /&gt;/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;&lt;br /&gt;/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;&lt;br /&gt;/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;&lt;br /&gt;mysqldump: Got error: 1721: You can't use locks with rpl info tables. when doing LOCK TABLES&lt;br /&gt;&lt;/pre&gt;This makes more difficult the operation of provisioning a slave from a backup. I would expect that, having stopped the slave, I could backup the table, possibly together with the rest of the database. Maybe MySQL has a hidden clever way of exporting this data, but if that exists, so far it has escaped me.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; You can use the following command to dump this table. &lt;br /&gt;&lt;pre&gt;mysqldump --master-data mysql slave_master_info&lt;/pre&gt;However, a simple &lt;pre&gt;mysqldump --master-data mysql&lt;/pre&gt;does not include the *_info tables. (&lt;a href="http://bugs.mysql.com/bug.php?id=60902"&gt;Bug#60902&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Another problem is maintenance. If I want to clean up the InnoDB table space, the usual recipe is to dump everything, stop the server, remove the ib* files, restart the server, and then reload the data.&lt;br /&gt;That has worked very well so far, because there were no innodb tables in the mysql database. Now, however, if we attempt to perform the above operation, we get an error when InnoDB comes online, because it won't find an internal reference to the innodb tables, whose .frm files (and possibly .ibd files) are still dangling around under the mysql folder.&lt;br /&gt;&lt;br /&gt;Incidentally, I can note that &lt;a href="http://tungsten-replicator.org/"&gt;Tungsten Replicator&lt;/a&gt; uses a similar approach (replication metadata is stored in a table, which is updated at every commit), and yet it does not suffer from any of the drawbacks mentioned here. The replication metadata tables are stored in a regular schema, which can be dumped just fine to provision a new slave. The additional commits are not a problem, since Tungsten uses the technique of block commits, where it commits together all the transactions that can be safely grouped.&lt;br /&gt;The safety of the slave thus depends on the value of --innodb-flush-log-at-trx-commit, not on additional trade off decisions.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;More to come.&lt;/h3&gt;This article covers just a portions of the replication improvements in 5.6. There is much more to see and test.&lt;br /&gt;Specifically, I want to test the performance impact of the metadata tables, and also the performance of the multi-threaded slave prototype against regular replication and Tungsten. I will get around to it shortly. Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-7503060295546583544?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/7503060295546583544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=7503060295546583544' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7503060295546583544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7503060295546583544'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/04/replication-metadata-in-mysql-562.html' title='Replication metadata in MySQL 5.6.2'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-6817480202584343378</id><published>2011-04-17T18:22:00.000+02:00</published><updated>2011-04-17T18:22:35.063+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='award'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Pewter for Tungsten - Thanks, MySQL community!</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://openlife.cc/blogs/2011/april/oreilly-mysql-conference-community-awards-2011-winners-are"&gt;&lt;img alt="community awards 2011" border="0" src="https://lh3.googleusercontent.com/_gVfZHGgf5LA/TaqzEopG-mI/AAAAAAAABG4/UBYWGctWWJk/tungsten_awards.png" title="Community awards 2011" width="250" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;After the opening keynote at the MySQL Conference, there was the usual ceremony of the MySQL community awards. Since Oracle declined to continue in the MySQL AB tradition of awarding the contributions from the community, the community itself has taken over.&lt;br /&gt;I was pleasantly surprised to find my name among the recipients, and even more about the prize awarded to my company's product, the &lt;a href="http://tungsten-replicator.org/"&gt;Tungsten Replicator&lt;/a&gt;.&lt;br /&gt;The surprise comes because we have been making noise about this product for only a few months, after we finalized our plans to split the company products between open source and enterprise. Apparently, it has been the right kind of noise, and the community has been able to see that Tungsten is a tangible contribution to the MySQL ecosystem. &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Now that the MySQL Conference's frenzy is over, we can continue making Tungsten even better than it is today. As probably everyone knows, we have found a generous sponsor (which should remain unnamed for now, but to whom we are very grateful) that is paying for implementing and strengthening the features that will make Tungsten 2.0 production ready in the near future.&lt;br /&gt;If users want to contribute with their feedback, they can download the binaries (and the full source code) from the new Tungsten home &lt;a href="http://tungsten-replicator.org/"&gt;http://tungsten-replicator.org&lt;/a&gt;, and report issues in the same site. See &lt;a href="http://scale-out-blog.blogspot.com/2011/04/settling-in-at-codegooglecom.html"&gt;Settling in at code.google.com&lt;/a&gt; for more information.&lt;br /&gt;More technical info will follow soon. &lt;br /&gt;For now, I just wanted to say &lt;b&gt;Thank you, MySQL community&lt;/b&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-6817480202584343378?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/6817480202584343378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=6817480202584343378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6817480202584343378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6817480202584343378'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/04/pewter-for-tungsten-thanks-mysql.html' title='Pewter for Tungsten - Thanks, MySQL community!'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/_gVfZHGgf5LA/TaqzEopG-mI/AAAAAAAABG4/UBYWGctWWJk/s72-c/tungsten_awards.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5185230084910529762</id><published>2011-04-15T03:00:00.002+02:00</published><updated>2011-04-15T03:00:06.829+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='opendatabasecamp'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Have you missed the MySQL Conference? Come to OpenDbCamp!</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.blogger.com/opendbcamp.org"&gt;&lt;img alt="opendbcamp" border="0" src="http://lh4.ggpht.com/_gVfZHGgf5LA/TSTzfrsx8_I/AAAAAAAABAg/XRCbqqZEYPM/open_database_sardinia.png" title="Open Database Camp 2011" width="200" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;The &lt;a href="http://mysqlconf.com"&gt;MySQL Conference&lt;/a&gt; is over. There have been many new developments, and the ones who have missed it will probably want to get a summary of the excitement, possibly from the people who have contributed to shaping the news. &lt;br /&gt;The &lt;a href="http://opendbcamp.org"&gt;Open Database Camp&lt;/a&gt; will give users an opportunity to catch up. Especially to open source users in Europe.&lt;br /&gt;Come and share the fun. There will be talks on MySQL, PostgreSQL, several NoSQL products, and a bunch of other cool stuff. &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5185230084910529762?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5185230084910529762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5185230084910529762' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5185230084910529762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5185230084910529762'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/04/have-you-missed-mysql-conference-come.html' title='Have you missed the MySQL Conference? Come to OpenDbCamp!'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_gVfZHGgf5LA/TSTzfrsx8_I/AAAAAAAABAg/XRCbqqZEYPM/s72-c/open_database_sardinia.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-8811542408729436192</id><published>2011-04-07T14:39:00.002+02:00</published><updated>2011-04-07T16:04:28.291+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='monitoring'/><title type='text'>Refactored again: poor man's MySQL replicator monitor</title><content type='html'>I saw that both Haidong Ji and Geert VanderKelen have proposed a Python monitor for MySQL replication, calling it the "poor man's version".&lt;br /&gt;See &lt;a href="http://www.haidongji.com/2011/04/06/poor-mans-mysql-replication-monitoring/"&gt;Poor man’s MySQL replication monitoring&lt;/a&gt; and Geert's &lt;a href="http://geert.vanderkelen.org/post/678/"&gt;Refactored: Poor man’s MySQL replication monitoring&lt;/a&gt;.&lt;br /&gt;Having Python in your server doesn't really qualify as "poor man". In many cases it's a luxury, and thus, here's my shot at the problem, using a Bash shell script.&lt;br /&gt;Unlike its Python-based competition, this version also checks that the slave is replicating from the intended master, and that it is not lagging behind.&lt;br /&gt;&lt;pre&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;USERNAME=msandbox&lt;br /&gt;PASSWORD=msandbox&lt;br /&gt;EXPECTED_MASTER_HOST=127.0.0.1&lt;br /&gt;EXPECTED_MASTER_PORT=27371&lt;br /&gt;&lt;br /&gt;SLAVE_HOST=127.0.0.1&lt;br /&gt;SLAVE_PORT=27372&lt;br /&gt;&lt;br /&gt;MYSQL="mysql -u $USERNAME -p$PASSWORD "&lt;br /&gt;MASTER="$MYSQL -h $EXPECTED_MASTER_HOST -P $EXPECTED_MASTER_PORT"&lt;br /&gt;SLAVE="$MYSQL -h $SLAVE_HOST -P $SLAVE_PORT"&lt;br /&gt;&lt;br /&gt;$MASTER -e 'SHOW MASTER STATUS\G' &amp;gt; mstatus&lt;br /&gt;$SLAVE -e 'SHOW SLAVE STATUS\G' &amp;gt; sstatus&lt;br /&gt;&lt;br /&gt;function extract_value {&lt;br /&gt;    FILENAME=$1&lt;br /&gt;    VAR=$2&lt;br /&gt;    grep -w $VAR $FILENAME | awk '{print $2}'&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Master_Binlog=$(extract_value mstatus File )&lt;br /&gt;Master_Position=$(extract_value mstatus Position )&lt;br /&gt;&lt;br /&gt;Master_Host=$(extract_value sstatus Master_Host)&lt;br /&gt;Master_Port=$(extract_value sstatus Master_Port)&lt;br /&gt;Master_Log_File=$(extract_value sstatus Master_Log_File)&lt;br /&gt;Read_Master_Log_Pos=$(extract_value sstatus Read_Master_Log_Pos)&lt;br /&gt;Slave_IO_Running=$(extract_value sstatus Slave_IO_Running)&lt;br /&gt;Slave_SQL_Running=$(extract_value sstatus Slave_SQL_Running)&lt;br /&gt;&lt;br /&gt;ERROR_COUNT=0&lt;br /&gt;if [ "$Master_Host" != "$EXPECTED_MASTER_HOST" ]&lt;br /&gt;then&lt;br /&gt;    ERRORS[$ERROR_COUNT]="the slave is not replicating from the host that it is supposed to"&lt;br /&gt;    ERROR_COUNT=$(($ERROR_COUNT+1))&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ "$Master_Port" != "$EXPECTED_MASTER_PORT" ]&lt;br /&gt;then&lt;br /&gt;    ERRORS[$ERROR_COUNT]="the slave is not replicating from the host that it is supposed to"&lt;br /&gt;    ERROR_COUNT=$(($ERROR_COUNT+1))&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ "$Master_Binlog" != "$Master_Log_File" ]&lt;br /&gt;then&lt;br /&gt;    ERRORS[$ERROR_COUNT]="master binlog ($Master_Binlog) and Master_Log_File ($Master_Log_File) differ"&lt;br /&gt;    ERROR_COUNT=$(($ERROR_COUNT+1))&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;POS_DIFFERENCE=$(echo ${Master_Position}-$Read_Master_Log_Pos|bc)&lt;br /&gt;&lt;br /&gt;if [ $POS_DIFFERENCE -gt 1000 ]&lt;br /&gt;then&lt;br /&gt;    ERRORS[$ERROR_COUNT]="The slave is lagging behind of $POS_DIFFERENCE"&lt;br /&gt;    ERROR_COUNT=$(($ERROR_COUNT+1))&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ "$Slave_IO_Running" == "No" ]&lt;br /&gt;then&lt;br /&gt;    ERRORS[$ERROR_COUNT]="Replication is stopped"&lt;br /&gt;    ERROR_COUNT=$(($ERROR_COUNT+1))&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ "$Slave_SQL_Running" == "No" ]&lt;br /&gt;then&lt;br /&gt;    ERRORS[$ERROR_COUNT]="Replication (SQL) is stopped"&lt;br /&gt;    ERROR_COUNT=$(($ERROR_COUNT+1))&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ $ERROR_COUNT -gt 0 ]&lt;br /&gt;then&lt;br /&gt;    EMAIL=myname@gmail.com&lt;br /&gt;    SUBJECT="ERRORS in replication"&lt;br /&gt;    BODY=''&lt;br /&gt;    CNT=0&lt;br /&gt;    while [ "$CNT" != "$ERROR_COUNT" ]&lt;br /&gt;    do&lt;br /&gt;        BODY="$BODY ${ERRORS[$CNT]}"&lt;br /&gt;        CNT=$(($CNT+1))&lt;br /&gt;    done&lt;br /&gt;    echo $SUBJECT&lt;br /&gt;    echo $BODY&lt;br /&gt;    echo $BODY | mail -s "$SUBJECT" $EMAIL&lt;br /&gt;else&lt;br /&gt;    echo "Replication OK"&lt;br /&gt;    printf "file: %s at %'d\n" $Master_Log_File  $Read_Master_Log_Pos&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-8811542408729436192?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/8811542408729436192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=8811542408729436192' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8811542408729436192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8811542408729436192'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/04/refactored-again-poor-mans-mysql.html' title='Refactored again: poor man&apos;s MySQL replicator monitor'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-4190167522564395834</id><published>2011-04-04T19:29:00.000+02:00</published><updated>2011-04-04T19:29:48.036+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='council'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Make your voice heard. Tell Oracle and the MySQL Council what bugs you</title><content type='html'>The &lt;a href="http://www.ioug.org/Events/IOUGWelcomesMySQL/tabid/164/Default.aspx"&gt;MySQL Council&lt;/a&gt; has not being idle. We have &lt;a href="http://datacharmer.blogspot.com/2011/03/mysql-council-addresses-public-bug.html"&gt;addressed the bugs database concerns&lt;/a&gt;, and we are continuing our dialog.&lt;br /&gt;To do a better job, we would like to hear more from the community. Unlike other established user groups, MySQL does not have a world wide organization for its users. The council exists on a voluntary basis, and we are seeking support from the rest of you. Please let your voice heard. There are three main channels for this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A MySQL Council survey&lt;/li&gt;&lt;li&gt;A set of questions that will be answered during the keynote at the MySQL Conference&lt;/li&gt;&lt;li&gt;Talk to a council member&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Survey&lt;/h3&gt;The &lt;a href="http://www.ioug.org/ImLookingFor/MySQLInformation/MySQLCommunitySurvey/tabid/202/e/1/Default.aspx"&gt;MySQL Council survey&lt;/a&gt; is an attempt to collect, understand, and eventually prioritize what the MySQL community feels, and act on their suggestions. It is a very short survey. We don't want your opinion on everything from barbecue sauce recipes to brain surgery. We need only a few lines about what bothers you the most with MySQL and how we can help. And of course, if &lt;i&gt;you&lt;/i&gt; wamt to help, we really want to hear about that.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Questions for the keynote&lt;/h3&gt;Let's ask Oracle directly. What are the biggest issues that you have? You can &lt;a href="https://spreadsheets.google.com/viewform?formkey=dHJrdVZ3SGdOUlRRYVVWZmlJT3FMWVE6MQ"&gt;submit your questions for the keynote&lt;/a&gt;, and Tomas Ulin will answer them on stage at the MySQL conference&lt;br /&gt;Here is your shot at practicing people power: think of the most pressing questions that you would see Tomas Ulin addressing, and submit them as soon as possible.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Talk to a council member&lt;/h3&gt;Council members are all well known people in the community. Most of us will be at the MySQL Conference or at Collaborate 11, or both. &lt;br /&gt;If you want to ask me questions about the council, or MySQL, or community matters, I will do my best to answer them, or to seek an answer if I don't know it myself.&lt;br /&gt;&lt;br /&gt;I will be at the &lt;a href="http://www.sfmysql.org/events/16826186/"&gt;San Francisco MySQL User Group&lt;/a&gt; on April 7th.&lt;br /&gt;Then I will be at the MySQL conference Monday and Tuesday. Oh, and there is the &lt;a href="http://2011mysqlcommunitydinnerwest.eventbrite.com/"&gt;Community Dinner West&lt;/a&gt; on Monday evening!&lt;br /&gt;On Wednesday, I will be at Collaborate 11.&lt;br /&gt;The other council members will be around as well. If you don't feel like filling the survey and prefer person-to-person communication, come see us, and let's talk!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-4190167522564395834?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/4190167522564395834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=4190167522564395834' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4190167522564395834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4190167522564395834'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/04/make-your-voice-heard-tell-oracle-and.html' title='Make your voice heard. Tell Oracle and the MySQL Council what bugs you'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5892674337997612357</id><published>2011-04-04T11:13:00.000+02:00</published><updated>2011-04-04T11:13:40.608+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='opendatabasecamp'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Open Database camp 2011 - Opportunities for sponsors, culture, and more</title><content type='html'>&lt;a href="http://opendbcamp.org"&gt;The Open Database Camp 2011&lt;/a&gt; is barely one month away.&lt;br /&gt;&lt;h3&gt;Sponsorship&lt;/h3&gt;Many thanks to all the sponsors! We very much appreciate your support.&lt;br /&gt;Speaking of what, here is some &lt;b&gt;important information for sponsors:&lt;/b&gt; The venue owners, Sardegna Ricerche, has given us the availabilkity of an ample hall for sponsors, where they can showcase their products and services.&lt;br /&gt;Each sponsor will have a desk, and a double panel sized cm 195 x 75 (6.3 x 2.4 feet).&lt;br /&gt; &lt;br /&gt;&lt;h3&gt;Culture, fun, and more&lt;/h3&gt;The Science park is something unique that geeks may want to visit. It is one of the biggest research centers in Europe, and the owners have graciously organized &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/#Around_the_conference"&gt;a guided tour before and after the conference&lt;/a&gt;.&lt;br /&gt;Near the conference there is Nora, an archeological site that alone is worth the trip for a visit. You can see it during the welcome party on Friday (if you show up before sunset, that is), or you can visit on your own after the conference.&lt;br /&gt;&lt;br /&gt;To give you an idea of what expects you, here is a promotional video of Sardegna Ricerche.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://3.gvt0.com/vi/L8JlnqFY6ds/0.jpg"&gt;&lt;param name="movie" value="http://www.youtube.com/v/L8JlnqFY6ds&amp;fs=1&amp;source=uds" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="320" height="266" src="http://www.youtube.com/v/L8JlnqFY6ds&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;More&lt;/h3&gt;The event should attract many local open source enthusiasts, with varying degrees of knowledge about open database. To meet their curiosity, there will be a parallel beginners track, with introductory sessions to open databases. SQL and noSQL fans, get ready to evangelize your beloved products. There will be many people eager to listen!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5892674337997612357?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5892674337997612357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5892674337997612357' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5892674337997612357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5892674337997612357'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/04/open-database-camp-2011-opportunities.html' title='Open Database camp 2011 - Opportunities for sponsors, culture, and more'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-8421614909107302899</id><published>2011-03-31T00:54:00.002+02:00</published><updated>2011-03-31T01:15:46.202+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='master'/><category scheme='http://www.blogger.com/atom/ns#' term='multiple'/><category scheme='http://www.blogger.com/atom/ns#' term='circular'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='webinar'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='slave'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='topology'/><title type='text'>MySQL replication for demanding users</title><content type='html'>I have been working with MySQL replication for quite a while. I have dealt with simple replication setups and I have experimented with complex ones. Five years ago I wrote &lt;a href="http://onlamp.com/pub/a/onlamp/2006/04/20/advanced-mysql-replication.html"&gt;an article about advanced MySQL replication&lt;/a&gt;, which was mostly a dream on what you could do with imagination and skill, but the matter from that article is still not even remotely ready for production. Yet, since that article, I have been approached by dozens of people who wanted to know how to make the multiple master dream become reality. To all of them, I had to say, "sorry, this is just a proof of concept.Come back in a few years, it may become possible". It still isn't.&lt;br /&gt;Despite its latest great technological advance, MySQL native replication is is very poor of topologies. What you can do with MySQL native replication is master-to-slave (which also includes relayed slaves), master-to-master, and circular replication.&lt;br /&gt;&lt;a href="https://www1.gotomeeting.com/register/973343952"&gt;&lt;img alt="replication topologies" border="0" src="https://lh5.googleusercontent.com/_gVfZHGgf5LA/TZOsJxleTgI/AAAAAAAABGg/K9_-cGboOgY/s720/topologies.png" title="some replication topologies" width="500" /&gt;&lt;/a&gt; &lt;br /&gt;Of these, circular replication is the closest thing to multiple masters that you can get with MySQL native replication, without the addition of third party services.&lt;br /&gt;Circular replication is tricky to set up, although not unreasonably so. It works. With some patience and precision, you can build a cluster of a few nodes in circular replication. With luck, you can get them to work properly, without loops and with the data flowing to all the servers. Your luck runs out the moment one of the servers fails, or replication breaks down for whatsoever reason. Then you see that circular replication is actually more complicated than what it looks on the surface, and it is also quite brittle. That doesn't mean that circular replication is not used in production. It is. I have known several people who use it successfully, although nobody is really happy about it.&lt;br /&gt;In addition to its fragility, circular replication is slow. If you insert data into master A, it has to travel across three nodes before reaching master D.&lt;br /&gt;Another topology that seems to be very popular is the multiple source scheme. It is the opposite of master/slave. Instead of having one master that sends data to many slaves, it is many masters that send data to one slave. Despite its popularity, this topology is yet unimplemented with MySQL native replication. The best you can do to simulate the desired outcome is to do round-robin replication with cron.&lt;br /&gt;With this background, it is no surprise that I was thrilled at the idea of working for a company that has made these dreams become reality. &lt;a href="http://code.google.com/p/tungsten-replicator/"&gt;Tungsten replicator&lt;/a&gt; allows users to have real multiple masters topologies, and even the much coveted multiple source topology is now within the users grasp.&lt;br /&gt;Compared to MySQL replication, the drawback of using Tungsten is that you need to deal with bigger complexity. It's only natural. With so many more features, there come more pieces to take care of.&lt;br /&gt;An interesting point about multiple masters is the matter of conflict resolution. Asynchronous replication convenience and robustness are countered by lack of means to deal with conflicts. This difficulty has been used many times as the reason for not implementing multiple source replication in MySQL. I have my own ideas on this issue. I am aware of the risks, but if I were allowed to do multiple master replication, I would be glad to take charge of the risks. Updating different databases, or different tables in separate masters is one way of defining a conflict-free scenario where multiple masters or multiple sources could be used safely. If only we could ...&lt;br /&gt;My colleague Robert Hodges has posted some interesting aspects in &lt;a href="http://scale-out-blog.blogspot.com/2011/03/slouching-towards-multi-master-conflict.html"&gt;his blog&lt;/a&gt;. The bottom line is that we focus on empowering users with advanced replication features. Conflict resolution can wait. I am sure many users would love to have the problem of how to avoid conflicts if the more demanding problem of how to replicate from many places to one cluster could be solved. The good news is that some sort of conflict detection (and possibly resolution) are possible even now, without slowing down the operations and without complicating our lives unnecessarily. For example, a simple conflict that could be avoided using Tungsten filters is the one resulting in a master that is updating tables that it was not supposed to do. In a scenario where multiple source replication works on the assumption that each master updates a given subset of the data, we can easily detect and eventually reject offending updates. It is not much, but in many practical cases it would be the difference between having robust multiple source replication and doing data load and consolidation manually.&lt;br /&gt;&lt;br /&gt;Anyway, back to the present day with very much real multi-master replication available for everyone. To alleviate the fear of the unknown, we are organizing webinars on a regular basis, where we cover the theoretical points and give practical demos of how to use the new features.&lt;br /&gt;If you are a demanding user, this upcoming webinar is for you: &lt;a href="https://www1.gotomeeting.com/register/973343952"&gt;MySQL Multi-Master and Multi-Source Replication With Tungsten&lt;/a&gt;. Tomorrow, March 31&lt;sup&gt;st&lt;/sup&gt;, 2011, at 10am PDT.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-8421614909107302899?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/8421614909107302899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=8421614909107302899' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8421614909107302899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8421614909107302899'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/mysql-replication-for-demanding-users.html' title='MySQL replication for demanding users'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/_gVfZHGgf5LA/TZOsJxleTgI/AAAAAAAABGg/K9_-cGboOgY/s72-c/topologies.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-826867274017850650</id><published>2011-03-17T13:18:00.003+01:00</published><updated>2011-03-17T17:25:59.624+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='parallel'/><title type='text'>How fast is parallel replication? See it live today</title><content type='html'>I talked about &lt;a href="http://datacharmer.blogspot.com/2011/02/advanced-replication-for-masses-part-ii.html"&gt;parallel replication&lt;/a&gt; last month. Since then, there has been a considerable interest for this feature. As far as I know, Tungsten's is the only implementation of this much coveted feature, so I can only compare with MySQL native replication.&lt;br /&gt;The most compelling question is "how fast is it?"&lt;br /&gt;That's a tricky one. The answer is the same that I give when someone asks me "how fast is MySQL". I always say: &lt;b&gt;it depends&lt;/b&gt;.&lt;br /&gt;Running replication in a single thread is sometimes slower than the operations in the master. Many users complain that the single thread can't keep up with the master, and the slave lags behind. True. There is, however, a hidden benefit of single threaded replication: it requires less resources. There is no contention for writing on disk, no need to worry about several users blocking a table. You need to contend with the users that want to read the tables, but the lone writer has an easy job, albeit a hard one.&lt;br /&gt;When we introduce parallel replication, the easy job fades away, and we are faced with the problem: how do I allow several writers to do the work of one? It's a nice problem to have. MySQL native replication does not allow parallel apply, but with Tungsten you can start tackling the issue of allowing several parallel threads to update the system at once. Therefore, this is the same problem that you have on a server where several users are allowed to write at once. If the server has sufficient resources, the operations will be fast. If it doesn't, the operations will lag behind.&lt;br /&gt;Another aspect of the question is "what kind of queries?" If your database is well established and set in stone, and you mostly UPDATEs, the replication performance will depend on how well your server is tuned for concurrent writes. If you run ALTER TABLE statements on a daily basis, your queries will queue up after that ALTER TABLE no matter what. And if you have only INSERT and DELETE queries, parallel replication will probably depend on how fast is your server.&lt;br /&gt;Ultimately, I can tell you that I have seen or experienced directly a wide range of repeatable results. I know cases where parallel replication is three times as fast as native replication. These cases usually involve huge amounts of binary logs, like in the case when your slave needs to be taken off-line for a few hours or even days and then it tries to catch up. Other cases that can be reproduced with a minimal amount of sample data show parallel replication as being 30% to 50% faster. ANd then there are cases when your server is so poor on resources or the load is so unevenly distributed that parallel replication is as fast as native replication. I would say that these cases are easily cured by beefing up the server.&lt;br /&gt;If you want to see a demo of how this replication works, you can join this webinar:&lt;br /&gt;&lt;a href="https://www1.gotomeeting.com/register/279070305"&gt;Zoom, Zoom, Zoom! MySQL Parallel Replication With Tungsten Replicator 2.0&lt;/a&gt;. &lt;br /&gt;You can tell from the title that we are quite excited about the product that we are building. &lt;br /&gt;&lt;!--And, BTW, this thing is open source. The code is on &lt;a href="http://code.google.com/p/tungsten-replicator/"&gt;Tungsten Replicator home&lt;/a&gt;.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-826867274017850650?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/826867274017850650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=826867274017850650' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/826867274017850650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/826867274017850650'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/how-fast-is-parallel-replication-see-it.html' title='How fast is parallel replication? See it live today'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-7877561910049733417</id><published>2011-03-15T01:27:00.001+01:00</published><updated>2011-03-15T17:01:15.290+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tricks'/><category scheme='http://www.blogger.com/atom/ns#' term='qa'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>Quick benchmarking trick</title><content type='html'>I have been doing quite a lot of benchmarking recently.&lt;br /&gt;I needed to find a safe way of measuring the time spend by the database doing a long task, like catching up on a huge backlog of accumulated replication updates. The problem with measuring this event is that I can record when it starts, but I can't easily detect when it finishes. My initial approach was to monitor the database and count the tables rows to see when the task was done, but I ended up affecting the task performance with my additional queries. So I thought of another method.&lt;br /&gt;Since I had control on what was sent from the master to the slave, I used the following:&lt;br /&gt;The initial time is calculated as the minimum creation time of the databases that I know are created during the exercise. Let's say that I had 5 databases named from db1 to db5: &lt;br /&gt;&lt;pre&gt;set @START = (select min(create_time) from information_schema.tables where table_schema like "db%")&lt;br /&gt;&lt;/pre&gt;Then, to make sure that I catch the exact moment that the task is finished, I added to the master a command for each database: &lt;br /&gt;&lt;pre&gt;create table db1.last_table (i int);&lt;br /&gt;create table db2.last_table (i int);&lt;br /&gt;create table db3.last_table (i int);&lt;br /&gt;create table db4.last_table (i int);&lt;br /&gt;create table db5.last_table (i int);&lt;br /&gt;&lt;/pre&gt;To know if the task is done, I query the database as follows:&lt;br /&gt;&lt;pre&gt;select count(*) from information_schema.tables where table_schema like "db%" and table_name="last_table";&lt;br /&gt;&lt;/pre&gt;If the count is less than 5 (the number of databases that were in my binary logs), I wait more.&lt;br /&gt;Finally, when the count matches the expected one, I get the end time:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;set @END = (select max(create_time) from information_schema.tables where table_schema like "db%" and table_name="last_table"');&lt;br /&gt;&lt;/pre&gt;Now I have two values, @START, and @END&lt;br /&gt;&lt;pre&gt;select timediff(@END,@START) as elapsed;&lt;br /&gt;+----------+&lt;br /&gt;| elapsed  |&lt;br /&gt;+----------+&lt;br /&gt;| 00:09:44 |&lt;br /&gt;+----------+&lt;br /&gt;&lt;/pre&gt;It does not matter if I query the database immediately, or hour after coming back from my errands. Using the table creation times makes sure that I get a clean start and finish time.&lt;br /&gt;I put all the above in a script, and I can check the elapsed time without fear of mistakes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-7877561910049733417?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/7877561910049733417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=7877561910049733417' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7877561910049733417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7877561910049733417'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/quick-benchmarking-trick.html' title='Quick benchmarking trick'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-7868156027734559179</id><published>2011-03-13T22:20:00.000+01:00</published><updated>2011-03-13T22:20:46.756+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iterm'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><category scheme='http://www.blogger.com/atom/ns#' term='terminal'/><category scheme='http://www.blogger.com/atom/ns#' term='dba'/><title type='text'>A cool terminal tip for Mac users</title><content type='html'>If you use a Mac, and you are dealing with many similar tasks at once, like examining many database servers in different terminals, you may like this one.&lt;br /&gt;I have been using &lt;a href="http://sites.google.com/site/iterm2home/"&gt;iTerm 2&lt;/a&gt; for a while, and my handling of parallel tasks has improved a lot. (No, I am not talking about &lt;a href="http://datacharmer.blogspot.com/2011/02/advanced-replication-for-masses-part-ii.html"&gt;Parallel replication&lt;/a&gt;, although I have applied this trick while testing that technology as well.)&lt;br /&gt;iTerm2 has some cool features, and probably the most striking one is &lt;a href="http://sites.google.com/site/iterm2home/screenshots"&gt;split panes&lt;/a&gt;. That alone would be a good reason for giving iTerm2 a try. But the one that I use the most, often in combination with Split Panes, is called &lt;i&gt;Send Input to all tabs&lt;/i&gt;.&lt;br /&gt;Here is how it works. &lt;br /&gt;Let's say I need to use 4 servers at once, and perform a non-repeating operation in all of them.&lt;br /&gt;So I open a separate window and I split the screen into 5 panes. I connect to each server in the first four panes, and I open a &lt;code&gt;vim&lt;/code&gt; instance in the fifth.&lt;br /&gt;With that done, I enable the magic option.&lt;br /&gt;&lt;img src="https://lh5.googleusercontent.com/_gVfZHGgf5LA/TX0zmfJCluI/AAAAAAAABGA/UQjgd_Yu7Bg/iTerm0.png" /&gt;&lt;br /&gt;&lt;br /&gt;A word of caution. This option sends the input to all the open tabs in your current window. If you don't want this to happen, do as I do, and open a separate window. Then make sure that all tabs, and eventually split panes, are supposed to receive your input. The application asks you for confirmation.&lt;br /&gt;&lt;a href="https://lh3.googleusercontent.com/_gVfZHGgf5LA/TX0slTS4-EI/AAAAAAAABF0/j6f080Sb-OE/s800/iTerm1.png" target="_blank"&gt;&lt;img src="https://lh3.googleusercontent.com/_gVfZHGgf5LA/TX0slTS4-EI/AAAAAAAABF0/j6f080Sb-OE/s800/iTerm1.png" width="500" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After that, whatever I type on one pane will be mirrored on all the panes. So I will see the commands running on my four servers, and being logged in a text file in the fifth one. All with just single command, I have all servers under control at once:&lt;br /&gt;&lt;a href="https://lh5.googleusercontent.com/_gVfZHGgf5LA/TX0sm5mYSPI/AAAAAAAABF8/ywMHYk313WQ/s800/iTerm3.png" target="_blank"&gt;&lt;img src="https://lh5.googleusercontent.com/_gVfZHGgf5LA/TX0sm5mYSPI/AAAAAAAABF8/ywMHYk313WQ/s800/iTerm3.png" width="500" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-7868156027734559179?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/7868156027734559179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=7868156027734559179' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7868156027734559179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7868156027734559179'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/cool-terminal-tip-for-mac-users.html' title='A cool terminal tip for Mac users'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/_gVfZHGgf5LA/TX0zmfJCluI/AAAAAAAABGA/UQjgd_Yu7Bg/s72-c/iTerm0.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-7751610380988312439</id><published>2011-03-13T15:22:00.000+01:00</published><updated>2011-03-13T15:22:32.949+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='partitioning'/><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='replication.conference'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>Replication and sandbox talks on the road - San Francisco, Santa Clara, Orlando</title><content type='html'>In a few weeks, I will be on the road, for an intense set of presentations in the USA.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;San Francisco, April 7th&lt;/h3&gt;I will start the tour at the San Francisco MySQL User Group. On April 7, at 6pm I will talk about &lt;a href="http://www.sfmysql.org/events/16826186/"&gt;Advanced MySQL replication for the masses&lt;/a&gt;. This talk will explore topics such as bi-directional replication, multiple sources, parallel replication, seamless failover, with the help of Tungsten replicator.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mysqlconf.com"&gt;&lt;br /&gt;&lt;img src="https://lh4.googleusercontent.com/_gVfZHGgf5LA/TXzR8kWl-LI/AAAAAAAABFk/jGwx2lbTqdE/mysql20111_speaking_badge_125x125.gif" width="125" height="125"  border="0"  alt="O'Reilly MySQL Conference &amp; Expo 2011" title="O'Reilly MySQL Conference &amp; Expo 2011"  /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Santa Clara, April 11, 12&lt;/h3&gt;The MySQL conference starts on Monday, April 11th, with several three-hour tutorials.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;April 11, 9:00am&lt;a href="http://en.oreilly.com/mysql2011/public/schedule/detail/17381"&gt;MySQL Replication Advanced Techniques&lt;/a&gt;. This will cover MySQL replication beyond the basics. Everything you can do with replication, including, tips, tricks, and gotchas, plus some really advanced things that you can achieve with third party tools.&lt;/li&gt;&lt;li&gt;On tutorial day, at 7pm, there will be the &lt;a href="http://www.bluegecko.net/news-events/2011-mysql-community-dinner-west-at-the-o%E2%80%99reilly-mysql-conference/"&gt;2011 MySQL community dinner (west)&lt;/a&gt;, organized by Sarah Novotny and probably attended by the best MySQLers in town. If you want to get the latest gossip and socialize with the top MySQL geeks, this is the place to be. &lt;/li&gt;&lt;li&gt;April 12, 11:55am &lt;a href="http://en.oreilly.com/mysql2011/public/schedule/detail/17391"&gt;The Art of Sandboxing - Reducing Complex Systems to Manageable Boxes&lt;/a&gt;. After the &lt;a href="http://en.oreilly.com/mysql2011/public/schedule/detail/18530"&gt;State of the Dolphin&lt;/a&gt;, here's a chance of learning a few practical tips on how to build respectful systems.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Robert Hodges and Edward Archibald will also be presenting at the MySQL Conference.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;April 11, 1:30pm &lt;a href="http://en.oreilly.com/mysql2011/public/schedule/detail/19268"&gt;Learn how to cure MySQL replication deprivation with Tungsten!&lt;/a&gt;&lt;/li&gt;&lt;li&gt; April 13, 2pm&lt;a href="http://en.oreilly.com/mysql2011/public/schedule/detail/17259"&gt;Preparing for the Big Oops: How to Build Disaster Recovery Sites for MySQL&lt;/a&gt;&lt;/li&gt;&lt;li&gt;TBD &lt;a href="http://en.oreilly.com/mysql2011/public/schedule/detail/19742"&gt;Build your own PaaS for MySQL with Tungsten Enterprise&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;On Tuesday evening I will fly to Orlando, to attend (part of) &lt;a href="http://collaborate11.ioug.org/tabid/133/Default.aspx"&gt;Collaborate11&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://collaborate11.ioug.org/tabid/133/Default.aspx"&gt;&lt;img src="https://lh4.googleusercontent.com/_gVfZHGgf5LA/TXzR875ElKI/AAAAAAAABFo/fJFRX0tE5ck/collaborate11_badge.png" alt="collaborate11 badge" title="Collaborate11"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Orlando, April 13&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;April 13, 1pm &lt;a href="http://coll11.mapyourshow.com/3_0/sessions/sessiondetails.cfm?ScheduledSessionID=2093"&gt;Dealing with large data with MySQL partitioning and replication&lt;/a&gt;. This talk will explain how to combine replication and partitioning to achieve performance, without any external tool.&lt;/li&gt;&lt;li&gt;April 13, 4pm&lt;a href="http://coll11.mapyourshow.com/3_0/sessions/sessiondetails.cfm?ScheduledSessionID=2148"&gt;MySQL Sandbox : a toolkit for productive laziness&lt;/a&gt;. One of my favorite subjects. How to use the MySQL Sandbox to achieve quick results with minimal effort&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-7751610380988312439?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/7751610380988312439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=7751610380988312439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7751610380988312439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7751610380988312439'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/replication-and-sandbox-talks-on-road.html' title='Replication and sandbox talks on the road - San Francisco, Santa Clara, Orlando'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/_gVfZHGgf5LA/TXzR8kWl-LI/AAAAAAAABFk/jGwx2lbTqdE/s72-c/mysql20111_speaking_badge_125x125.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-516542946399702869</id><published>2011-03-08T10:29:00.000+01:00</published><updated>2011-03-08T10:29:08.287+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='council'/><title type='text'>The MySQL Council addresses the public bug database issue</title><content type='html'>When I announced the &lt;a href="http://datacharmer.blogspot.com/2011/01/mysql-council-is-up-and-running-we-want.html"&gt;MySQL Council&lt;/a&gt;, I said that among its roles there is that of being a bridge between the MySQL community and Oracle.&lt;br /&gt;It has come the time where we put this role to good use. Recently, there have been some concerns about the MySQL bugs database, which could be summarized in Mark Callaghan's post &lt;a href="http://mysqlha.blogspot.com/2011/02/where-have-bugs-gone.html"&gt;Where have the bugs gone?&lt;/a&gt;. &lt;br /&gt;The gist of the concerns is that there has been a change in the bugs handling, although we don't know what was changed and how. In short, there has been a total lack of communication. The MySQL Council has addressed the concerns about the &lt;a href="http://bugs.mysql.com/"&gt;public bug database&lt;/a&gt; in a recent meeting, and has taken several steps, like approaching Oracle directly, and releasing a &lt;a href="http://www.ioug.org/Events/IOUGWelcomesMySQL/tabid/164/Default.aspx"&gt;summary of the concerns&lt;/a&gt; in its site.&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;&lt;br /&gt;The MySQL Council members have been discussing the decision by Oracle, to reduce the importance of the public MySQL bug database for providing input and direction of product updates and direction. The Council would also like to work with Oracle to promote communication around the status of the database access to the broader community so members will understand what to expect moving forward.&lt;br /&gt;&lt;br /&gt;Without communication around the use and changes relating to the public bug database, there have been concerns in the community raised about duplicate bug tracking, bug numbers in commits not being visible to the public, difficulty in offering patches into the MySQL server, and the generalized decreased transparency in the evolution and remediation of the MySQL server and associated products.&lt;br /&gt;&lt;br /&gt;The IOUG (Independent Oracle User Group) is supporting the MySQL Council in its efforts to raise questions and query direction from Oracle.  The MySQL Council will be meeting with Oracle stakeholders to discuss options for keeping appropriate portions of the database active as well as communicating status and future actions to the broader community.&lt;br /&gt;&lt;/i&gt;&lt;/blockquote&gt;We don't know the outcome yet. But we'll surely post an update as soon as we hear  it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-516542946399702869?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/516542946399702869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=516542946399702869' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/516542946399702869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/516542946399702869'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/mysql-council-addresses-public-bug.html' title='The MySQL Council addresses the public bug database issue'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5071187116027681627</id><published>2011-03-07T10:43:00.002+01:00</published><updated>2011-03-07T11:44:40.488+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tricks'/><category scheme='http://www.blogger.com/atom/ns#' term='limit'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='quota'/><category scheme='http://www.blogger.com/atom/ns#' term='table'/><category scheme='http://www.blogger.com/atom/ns#' term='dba'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>implementing table quotas in MySQL</title><content type='html'>I have just seen &lt;a href="http://code.openark.org/blog/mysql/limiting-table-disk-quota-in-mysql"&gt;Limiting table disk quota in MySQL&lt;/a&gt; by Shlomi Noach, and I could not resist.&lt;br /&gt;You can actually implement a disk quota using an updatable view with the &lt;a href="http://dev.mysql.com/doc/refman/5.5/en/create-view.html"&gt;CHECK OPTION&lt;/a&gt;.&lt;br /&gt;Instead of giving the user access to the table, you give access to the view (at least for inserting, see the caveat at the end), and you will get a genuine MySQL error when the limit is reached.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;drop table if exists logs;&lt;br /&gt;create table logs (t mediumtext) engine=innodb;&lt;br /&gt;&lt;br /&gt;drop function if exists exceeded_logs_quota ;&lt;br /&gt;create function exceeded_logs_quota() &lt;br /&gt;returns boolean&lt;br /&gt;deterministic&lt;br /&gt;return (&lt;br /&gt;    select CASE &lt;br /&gt;           WHEN (DATA_LENGTH + INDEX_LENGTH) &amp;gt; (25*1024) &lt;br /&gt;           THEN TRUE ELSE FALSE &lt;br /&gt;           END&lt;br /&gt;    FROM &lt;br /&gt;        information_schema.tables &lt;br /&gt;    WHERE &lt;br /&gt;        table_schema=schema() &lt;br /&gt;        and table_name='logs'&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;create or replace view logsview as &lt;br /&gt;    SELECT * FROM logs &lt;br /&gt;    WHERE &lt;b&gt;NOT exceeded_logs_quota()&lt;/b&gt;&lt;br /&gt;    WITH &lt;b&gt;CHECK OPTION&lt;/b&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here's a test run:&lt;br /&gt;&lt;pre&gt;mysql [localhost] {msandbox} (test) &amp;gt; insert into logsview values ('a');&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql [localhost] {msandbox} (test) &amp;gt; select exceeded_logs_quota();&lt;br /&gt;+-----------------------+&lt;br /&gt;| exceeded_logs_quota() |&lt;br /&gt;+-----------------------+&lt;br /&gt;|                     0 |&lt;br /&gt;+-----------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql [localhost] {msandbox} (test) &amp;gt; insert into logsview values (repeat('a', (25 * 1024) - 1));&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql [localhost] {msandbox} (test) &amp;gt; select exceeded_logs_quota();&lt;br /&gt;+-----------------------+&lt;br /&gt;| exceeded_logs_quota() |&lt;br /&gt;+-----------------------+&lt;br /&gt;|                     1 |&lt;br /&gt;+-----------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql [localhost] {msandbox} (test) &amp;gt; insert into logsview values ('b');&lt;br /&gt;ERROR 1369 (HY000): CHECK OPTION failed 'test.logsview'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You will need to twist the limit to adapt to InnoDB habits of allocating pages rather than bytes, but if you measure the limit in MB the method should work fine.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;CAVEAT: &lt;/b&gt; You should give your users separate privileges: SELECT on &lt;code&gt;logs&lt;/code&gt;, and INSERT on &lt;code&gt;logsview&lt;/code&gt;. The view will only return records while &lt;code&gt;exceeded_logs_quota()&lt;/code&gt; returns false.&lt;br /&gt;&lt;pre&gt;mysql [localhost] {msandbox} (test) &amp;gt; select exceeded_logs_quota();&lt;br /&gt;+-----------------------+&lt;br /&gt;| exceeded_logs_quota() |&lt;br /&gt;+-----------------------+&lt;br /&gt;|                     1 |&lt;br /&gt;+-----------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;mysql [localhost] {msandbox} (test) &amp;gt; select count(*) from logsview;&lt;br /&gt;+----------+&lt;br /&gt;| count(*) |&lt;br /&gt;+----------+&lt;br /&gt;|        0 |&lt;br /&gt;+----------+&lt;br /&gt;1 row in set (0.01 sec)&lt;br /&gt;&lt;br /&gt;mysql [localhost] {msandbox} (test) &amp;gt; select count(*) from logs;&lt;br /&gt;+----------+&lt;br /&gt;| count(*) |&lt;br /&gt;+----------+&lt;br /&gt;|        2 |&lt;br /&gt;+----------+&lt;br /&gt;1 row in set (0.01 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5071187116027681627?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5071187116027681627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5071187116027681627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5071187116027681627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5071187116027681627'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/implementing-table-quotas-in-mysql.html' title='implementing table quotas in MySQL'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-3947975739184982482</id><published>2011-03-06T18:44:00.000+01:00</published><updated>2011-03-06T18:44:37.482+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='advanced'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='topology'/><title type='text'>Advanced replication for the masses - Part III - Replication topologies</title><content type='html'>After &lt;a href="http://datacharmer.blogspot.com/2011/02/advanced-replication-for-masses-part-i.html"&gt;part I: the basics&lt;/a&gt;, and &lt;a href="http://datacharmer.blogspot.com/2011/02/advanced-replication-for-masses-part-ii.html"&gt;part II: parallel apply&lt;/a&gt;, we deal now with some more mundane topic, or how to deploy replication services in a way that they fit our business, covering from the basic master/slave to the most advanced multi-source scheme.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Master/slave&lt;/h3&gt;The most common topology is master/slave. One master, many slaves. This topology is equivalent to MySQL native replication. The differences are in the additional features. Tungsten supports seamless failover and parallel replication in all topologies. &lt;br /&gt;&lt;img src="https://lh6.googleusercontent.com/_gVfZHGgf5LA/TXO036CvQvI/AAAAAAAABEA/Iglwg8uzCuI/Tungsten_master_slave_replication.png" /&gt;&lt;br /&gt;&lt;i&gt;Figure 1. Tungsten master/slave replication&lt;/i&gt;&lt;br /&gt;Unlike MySQL, and unlike previous versions of Tungsten, the implementation of this topology uses a dedicated service for the master, and deploys a corresponding service on each slave. In MySQL, and old Tungsten, there is just a general purpose pipeline that connects from master to slave. In Tungsten Replicator, instead, you need to define a service explicitly. While this requirement looks like overkill for such a simple topology, it will be clear that it helps defining advanced topologies.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Relayed replication&lt;/h3&gt;The first time that I saw this topology with Tungsten, it was by mistake. I wanted to connect host Delta with host Alpha, but by a combination of bad cut-and-paste and mindlessness, I connected the slave Delta to a seemingly non-existent master Bravo (figure 2). &lt;br /&gt;&lt;img src="https://lh5.googleusercontent.com/_gVfZHGgf5LA/TXO03RuE55I/AAAAAAAABD4/kEHOzur5FQg/Tungsten_master_slave_replication_wrong.png" /&gt;&lt;br /&gt;&lt;i&gt;Figure 2. Tungsten master/slave replication with relay&lt;/i&gt;&lt;br /&gt;The funny thing is that I did not realize the error, because the test that I wrote to certify that what I inserted in the master was then usable in all the slaves, worked without a problem. Thus I learned another feature of Tungsten: &lt;b&gt;every slave is also a relay slave&lt;/b&gt;, without need of any additional setup. It does not matter if the slave is using binary logs, or if it has enabled the &lt;i&gt;logs-slave-updates&lt;/i&gt; option. Those requirements are for MySQL native replication. Tungsten slave replicator services can detect a request from another slave, and act as a relay slave if necessary.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Bi-directional replication&lt;/h3&gt;Here is where people used to MySQL replication start to be surprised. To set a master-to-master topology, we deploy two services for each host. The first host sets a master service named &lt;i&gt;alpha&lt;/i&gt;, and a remote slave service named &lt;i&gt;bravo&lt;/i&gt;. The second host does the opposite: a local master service named &lt;i&gt;bravo&lt;/i&gt;, and a remote slave service named &lt;i&gt;alpha&lt;/i&gt;. (Figure 3)&lt;br /&gt;&lt;img src="https://lh5.googleusercontent.com/_gVfZHGgf5LA/TXO2MfOUagI/AAAAAAAABEc/jvt9lZC8uvY/Tungsten_bi_directional_replication.png"&gt;&lt;br /&gt;&lt;i&gt;Figure 3. Tungsten bi-directional replication&lt;/i&gt;&lt;br /&gt;Whatever is updated on host alpha is processed and sent to remote slaves by the master replicator service &lt;i&gt;alpha&lt;/i&gt;. Whatever is updated in host bravo is processed by the master replicator service &lt;i&gt;bravo&lt;/i&gt; and dispatched to its audience. &lt;br /&gt;This system works like MySQL master-to-master replication. There is no conflict resolution handling. The prerequisite, for this and the following topologies, is that you know what you are doing and leverage the replication system within its limitations.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Multiple site replication&lt;/h3&gt;This is an extension of bi-directional replication. For each master, there is one or more slaves. Figure 4 shows a typical implementation. You have a main site in one location, and want to have a backup system in another location. If disaster strikes in your main location, you are ready to switch over to the alternate site with minimum delay.&lt;br /&gt;&lt;img src="https://lh3.googleusercontent.com/_gVfZHGgf5LA/TXO03JdfIEI/AAAAAAAABD8/MG-tyymZvfI/s800/Tungsten_bi_directional_replication.png"&gt;&lt;br /&gt;&lt;i&gt;Figure 4. Tungsten multiple site replication&lt;/i&gt;&lt;br /&gt;The reliability and robustness of this scheme depends on your applications. Nothing prevents you from writing to both masters at once. And if you keep the tasks logically separated (e.g. master alpha writes on database products, while master bravo writes on database employees) nothing bad will happen. But if your applications update the same records, you can suffer either a duplicate key error or silent loss of changes when a master writes on top of an already updated record.&lt;br /&gt;This topology is frequently used in combination with a virtual IP provider, a system that shields both clusters from the application's view, and let it connect through an IP that is associated to the active master. There are many such systems, including Linux HA and Tungsten Enterprise. But that is beyond the scope of this post.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Multiple source replication&lt;/h3&gt;This topology is extremely popular, at least judging from the many times that it has been requested to me. So strangely popular, in fact, because it does not exist, at least as far as MySQL replication is concerned. One of the limits of MySQL native replication is that every slave can have only one master.&lt;br /&gt;This topology has been explained to me in many ways. One of the most common is this. You have a company that has a headquarters in a town, say New York. That company has stores in many cities, and the management would like to get the data from each store to the headquarters, in real time. This is the opposite of the master/slave topology, and no matter how creative you become, you can't get MySQL to do it.&lt;br /&gt;Using Tungsten, you can implement this topology fairly easily. (Figure 5)&lt;br /&gt;&lt;img src="https://lh6.googleusercontent.com/_gVfZHGgf5LA/TXO04pRkW0I/AAAAAAAABEE/Ws3-Py7RMdE/Tungsten_multi_source_replication.png"&gt;&lt;br /&gt;&lt;i&gt;Figure 5. Tungsten multiple source replication&lt;/i&gt;&lt;br /&gt;Each server deploys a master replicator service. The host in headquarters deploys one slave service for each of the remote masters.&lt;br /&gt;Of course, there is no conflict resolution handling. If you r remote masters don't behave within the limits that you want them to have, you will get in trouble, and replication may stop. However, if you know what you're doing and set the system properly, at least you can achieve the goal of getting this reverse replication scheme working smoothly.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Hands on&lt;/h3&gt;To help the early adopters, I have put together a set of scripts that deploy easily any of the topologies mentioned in this post with just a few actions. &lt;br /&gt;What you need is 4 hosts (four copies of the virtual machine mentioned in &lt;a href="http://datacharmer.blogspot.com/2011/02/advanced-replication-for-masses-part-i.html"&gt;part I&lt;/a&gt; will do), and the Tungsten deployer package that you will get from the &lt;a href="http://code.google.com/p/tungsten-replicator/downloads/list"&gt;Tungsten downloads&lt;/a&gt; page.&lt;br /&gt;Once you have the four server, unpack the deployer scripts on a chosen directory in all servers, making sure that the directory is the same in all four. Inside the package, there is a README file with a detailed list of instructions. So detailed, in fact, that I won't copy it here because it would make this post too long.&lt;br /&gt;&lt;br /&gt;I will just show a sample run:&lt;br /&gt;&lt;pre&gt;$ ./set_multi_source.sh &lt;br /&gt;QA1&lt;br /&gt;installation OK&lt;br /&gt;&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 0&lt;br /&gt;appliedLatency  : 1.243&lt;br /&gt;role            : &lt;b&gt;master&lt;/b&gt;&lt;br /&gt;serviceName     : &lt;b&gt;alpha&lt;/b&gt;&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;Finished services command...&lt;br /&gt;&lt;br /&gt;QA2&lt;br /&gt;installation OK&lt;br /&gt;&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 0&lt;br /&gt;appliedLatency  : 1.264&lt;br /&gt;role            : &lt;b&gt;master&lt;/b&gt;&lt;br /&gt;serviceName     : &lt;b&gt;bravo&lt;/b&gt;&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;Finished services command...&lt;br /&gt;&lt;br /&gt;QA3&lt;br /&gt;installation OK&lt;br /&gt;&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 0&lt;br /&gt;appliedLatency  : 0.812&lt;br /&gt;role            : &lt;b&gt;master&lt;/b&gt;&lt;br /&gt;serviceName     : &lt;b&gt;charlie&lt;/b&gt;&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;Finished services command...&lt;br /&gt;&lt;br /&gt;QA4&lt;br /&gt;installation OK&lt;br /&gt;&lt;br /&gt;Processing services command...&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 0&lt;br /&gt;appliedLatency  : 29.521&lt;br /&gt;role            : &lt;b&gt;slave&lt;/b&gt;&lt;br /&gt;serviceName     : &lt;b&gt;alpha&lt;/b&gt;&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 0&lt;br /&gt;appliedLatency  : 20.123&lt;br /&gt;role            : &lt;b&gt;slave&lt;/b&gt;&lt;br /&gt;serviceName     : &lt;b&gt;bravo&lt;/b&gt;&lt;br /&gt;serviceType     : remote&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 0&lt;br /&gt;appliedLatency  : 12.726&lt;br /&gt;role            : &lt;b&gt;slave&lt;/b&gt;&lt;br /&gt;serviceName     : &lt;b&gt;charlie&lt;/b&gt;&lt;br /&gt;serviceType     : remote&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;Finished services command...&lt;br /&gt;&lt;br /&gt;$ ./test_flow_multi_source.sh &lt;br /&gt;inserting 100 into each of the three masters. Please wait&lt;br /&gt;Retrieving data from the masters&lt;br /&gt;QA1&lt;br /&gt;+----+-----+------+&lt;br /&gt;| t  | c   | s    |&lt;br /&gt;+----+-----+------+&lt;br /&gt;| t1 | 100 | 5050 |&lt;br /&gt;+----+-----+------+&lt;br /&gt;&lt;br /&gt;QA2&lt;br /&gt;+----+-----+------+&lt;br /&gt;| t  | c   | s    |&lt;br /&gt;+----+-----+------+&lt;br /&gt;| t2 | 100 | 5050 |&lt;br /&gt;+----+-----+------+&lt;br /&gt;&lt;br /&gt;QA3&lt;br /&gt;+----+-----+------+&lt;br /&gt;| t  | c   | s    |&lt;br /&gt;+----+-----+------+&lt;br /&gt;| t3 | 100 | 5050 |&lt;br /&gt;+----+-----+------+&lt;br /&gt;&lt;br /&gt;Retrieving data from the slave&lt;br /&gt;QA4&lt;br /&gt;+----+-----+------+&lt;br /&gt;| t  | c   | s    |&lt;br /&gt;+----+-----+------+&lt;br /&gt;| t1 | 100 | 5050 |&lt;br /&gt;| t2 | 100 | 5050 |&lt;br /&gt;| t3 | 100 | 5050 |&lt;br /&gt;+----+-----+------+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Happy hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-3947975739184982482?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/3947975739184982482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=3947975739184982482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3947975739184982482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3947975739184982482'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/advanced-replication-for-masses-part.html' title='Advanced replication for the masses - Part III - Replication topologies'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/_gVfZHGgf5LA/TXO036CvQvI/AAAAAAAABEA/Iglwg8uzCuI/s72-c/Tungsten_master_slave_replication.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-4630304106053338407</id><published>2011-03-05T20:32:00.001+01:00</published><updated>2011-03-05T23:33:54.814+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tricks'/><category scheme='http://www.blogger.com/atom/ns#' term='options'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='prompt'/><category scheme='http://www.blogger.com/atom/ns#' term='dba'/><title type='text'>A hidden options file trick</title><content type='html'>I was listening today to the &lt;a href="http://technocation.org/content/oursql-episode-36%3A-it%2526%2523039;s-not-our-(de)fault!-part-1"&gt;OurSQL Episode 36: It's Not Our (De)fault! Part 1&lt;/a&gt;. As usual, Sheeri and Sarah are very informational and entertaining while explaining the innards of MySQL and their best practices.&lt;br /&gt;Being a DBA oriented show, there was an omission in this podcast. There was no mention of custom groups that you can have for your my.cnf. This is mostly useful for developers. If your application requires some specific settings, instead of using a separated configuration file, you can use a different group, and then instruct your client applications to use that group.&lt;br /&gt;By default, all client applications read the "[client]" group.&lt;br /&gt;But you can tell your client to read a group that you can call whatever you like.&lt;br /&gt;For example, with this configuration file,&lt;br /&gt;&lt;pre&gt;[client]&lt;br /&gt;user=common_user&lt;br /&gt;password=common_password&lt;br /&gt;&lt;br /&gt;[logrotation]&lt;br /&gt;user=log_rotation_daemon&lt;br /&gt;password=specific_password&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can have a Perl script that takes care of your particular log rotation needs. Instead of the normal credentials, it will use the ones listed in the [logrotation] group.&lt;br /&gt;&lt;pre&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;use DBI;&lt;br /&gt;&lt;br /&gt;my $dsn =   "DBI:mysql:test;"&lt;br /&gt;            . "mysql_read_default_group=logrotation;"&lt;br /&gt;            . "mysql_read_default_file=$ENV{HOME}/./my.cnf";&lt;br /&gt;my $dbh = DBI-&gt;connect($dsn);&lt;br /&gt;&lt;/pre&gt;Notice that, for this option to work, the [logrotation] group must come &lt;b&gt;after&lt;/b&gt; the [client] group, or the directives in the [client] group will override the ones in [logrotation]. That's why, in the options file, you find the directives for [mysqldump] at the bottom of the file.&lt;br /&gt;&lt;br /&gt;So far, so good. This was a trick for developers, and probably many developers know it already. But there is another, related trick, that can be used by non-developers as well.&lt;br /&gt;If you knew about these customized groups, you may have realized that you can't use them with the mysql standard command line client. Or, to say it better, there is no clearly documented way of doing so. There is, in fact, a cute trick that you can use.&lt;br /&gt;Let's say that, from time to time, you want to use a different prompt, but you don't want to edit your $HOME/.my.cnf to change it. You just want your prompt to be there in the option file, and be able to recall it when the situation calls for it.&lt;br /&gt;The mysql internal help does not tell anything about groups. However, a careful search of the manual gives this cryptic &lt;a href="http://dev.mysql.com/doc/refman/5.5/en/my-print-defaults.html"&gt;entry&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;--defaults-group-suffix=suffix, -g suffix&lt;br /&gt;&lt;br /&gt;In addition to the groups named on the command line, read groups that have the given suffix. &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;When I found it, I stared at this puzzling statement for a while. I could not understand which are the groups that are &lt;i&gt;named in the command line&lt;/i&gt;. &lt;br /&gt;Eventually, I figured out why there is a &lt;i&gt;group-suffix&lt;/i&gt; and not simply a &lt;i&gt;group&lt;/i&gt;. It means that if you add a suffix to a default group name, and you tell mysql to look for this suffix, then you will be able to use the appropriate group on demand.&lt;br /&gt;For example, this options file &lt;b&gt;will not work&lt;/b&gt;.&lt;br /&gt;&lt;pre&gt;# wrong&lt;br /&gt;[pinocchio]&lt;br /&gt;prompt='I have a long nose  =======&amp;gt; '&lt;br /&gt;&lt;br /&gt;[master]&lt;br /&gt;prompt='master [\h] {\u} (\d) &amp;gt; '&lt;br /&gt;&lt;br /&gt;[slave]&lt;br /&gt;prompt='slave [\h] {\u} (\d) &amp;gt; '&lt;br /&gt;&lt;/pre&gt;But this one will work:&lt;br /&gt;&lt;pre&gt;[mysqlpinocchio]&lt;br /&gt;prompt='I have a long nose  =======&amp;gt; '&lt;br /&gt;&lt;br /&gt;[mysqlmaster]&lt;br /&gt;prompt='master [\h] {\u} (\d) &amp;gt; '&lt;br /&gt;&lt;br /&gt;[mysqlslave]&lt;br /&gt;prompt='slave [\h] {\u} (\d) &amp;gt; '&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is a test run:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ mysql --defaults-group-suffix=pinocchio&lt;br /&gt;Welcome to the MySQL monitor.  Commands end with ; or \g.&lt;br /&gt;Your MySQL connection id is 22&lt;br /&gt;Server version: 5.1.54 MySQL Community Server (GPL)&lt;br /&gt;&lt;br /&gt;Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.&lt;br /&gt;&lt;br /&gt;Oracle is a registered trademark of Oracle Corporation and/or its&lt;br /&gt;affiliates. Other names may be trademarks of their respective&lt;br /&gt;owners.&lt;br /&gt;&lt;br /&gt;Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.&lt;br /&gt;&lt;br /&gt;I have a long nose  =======&amp;gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The meaning of the &lt;i&gt;suffix&lt;/i&gt; part is that mysql will read the default groups (which are [client], and [mysql]), and it will also read any groups that are named "mysqlSUFFIX" or "clientSUFFIX". I have named the group "&lt;b&gt;mysql&lt;/b&gt;pinocchio" and therefore it has been used. It would have worked the same if I had called it "&lt;b&gt;client&lt;/b&gt;pinocchio".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-4630304106053338407?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/4630304106053338407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=4630304106053338407' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4630304106053338407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4630304106053338407'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/hidden-options-file-trick.html' title='A hidden options file trick'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1826174491188087532</id><published>2011-03-02T16:25:00.000+01:00</published><updated>2011-03-02T16:25:49.264+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qa'/><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='logs'/><category scheme='http://www.blogger.com/atom/ns#' term='detect'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>beware of the log</title><content type='html'>The MySQL &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/query-log.html"&gt;general log&lt;/a&gt; is one of my favorite features for a quick debug. I especially like the ability of starting and stopping it on demand, which was introduced in MySQL 5.1.&lt;br /&gt;However, using the general log has its drawbacks.&lt;br /&gt;Today I was debugging a nasty bug that results from two statements that should be applied sequentially, but that were instead concurrent. These kind of problems are hard to cope with, as they are intermittent. Sometimes all goes well, and you get the expected result. And then, sometimes the statements fly on different directions and I stare at the screen, trying to understand where did they stray. &lt;br /&gt;After some try-and-fail, I decided to enable the general log just before the offending statements, and to turn it down immediately after. Guess what? With the general log on, the test &lt;b&gt;never&lt;/b&gt; failed. What was an intermittently failing test became an always succeeding test. &lt;br /&gt;What happened is that the general log delayed the query execution just enough for the following statement to arrive when it was expected. &lt;br /&gt;In the end, the bug had to be unveiled using white box techniques.&lt;br /&gt;Moral of the story: using a general log alters the status of the server. If you use it, be prepared to deal with its side effects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1826174491188087532?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1826174491188087532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1826174491188087532' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1826174491188087532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1826174491188087532'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/03/beware-of-log.html' title='beware of the log'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5992067812308065594</id><published>2011-02-25T11:09:00.000+01:00</published><updated>2011-02-25T11:09:33.013+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shards'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='trepctl'/><category scheme='http://www.blogger.com/atom/ns#' term='advanced'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='clustering'/><category scheme='http://www.blogger.com/atom/ns#' term='tasks'/><category scheme='http://www.blogger.com/atom/ns#' term='parallel'/><category scheme='http://www.blogger.com/atom/ns#' term='status'/><title type='text'>Advanced replication for the masses - Part II - Parallel replication</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://code.google.com/p/tungsten-replicator/"&gt;&lt;img alt="parallel_replication_image" border="0" src="https://lh3.googleusercontent.com/_gVfZHGgf5LA/TWbezv9WHgI/AAAAAAAABDA/2VhJUDbAIdM/Tungsten_parallel_replication.png" title="Tungsten Parallel Replication" width="500" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;I hope you liked the &lt;a href="http://datacharmer.blogspot.com/2011/02/advanced-replication-for-masses-part-i.html"&gt;first part&lt;/a&gt; of this series of lessons. And I really hope that you have followed the instructions and got your little replication cluster up and working.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;If you haven't done that, thinking that you would spare your energies for more juicy matters, I have news for you. What I explained in the previous part is exactly what you need to do to set up parallel replication. &lt;i&gt;With just a tiny additional detail.&lt;/i&gt;&lt;br /&gt;For the sake of the diligent readers who have followed the instructions with the first lessons, I won't repeat them, but I'll invite you to set the environment as explained in the first part.&lt;br /&gt;Once you have a cluster up and running, and you can confirm that replication is indeed working with Tungsten, you can remove all with the &lt;code&gt;clear_cluster.sh&lt;/code&gt; script, and launch again the &lt;code&gt;set_installation.sh&lt;/code&gt; script, with the tiny detail we have mentioned above.&lt;br /&gt;The astute readers may have noticed that the installation script contains these lines:&lt;br /&gt;&lt;pre&gt;...&lt;br /&gt;&lt;b&gt;MORE_OPTIONS&lt;/b&gt;=$1&lt;br /&gt;./configure-service --create --role=master &lt;b&gt;$MORE_OPTIONS&lt;/b&gt; logos1&lt;br /&gt;./tungsten-replicator/bin/trepctl -service logos1 start&lt;br /&gt;&lt;br /&gt;./configure-service --create --role=slave --master-host=QA2 \&lt;br /&gt;    --service-type=remote &lt;b&gt;$MORE_OPTIONS&lt;/b&gt; logos2&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;This means that you can start &lt;code&gt;set_replication.sh&lt;/code&gt; with one additional option, which will be passed to the creation of the Tungsten service. Without further suspense, the addition that you need is &lt;code&gt;&lt;b&gt;--channels=5&lt;/b&gt;&lt;/code&gt;.&lt;br /&gt;Yep. It was that easy.&lt;br /&gt;&lt;pre&gt;./set_replication.sh --channels=5&lt;br /&gt;&lt;/pre&gt;This little addition will start your Tungsten replicator, apparently in the same way it did before. But there is a substantial difference. While the data is funneled from the master to the slaves in the usual way, the applier splits the data by database. You can see the difference as soon as you send some data through the pipeline.&lt;br /&gt;&lt;pre&gt;#master&lt;br /&gt;mysql -h tungsten1 -e 'create schema mydb1'&lt;br /&gt;mysql -h tungsten1 -e 'create schema mydb2'&lt;br /&gt;mysql -h tungsten1 -e 'create schema mydb3'&lt;br /&gt;mysql -h tungsten1 -e 'create table mydb1.t1 (i int)'&lt;br /&gt;mysql -h tungsten1 -e 'create table mydb2.t1 (i int)'&lt;br /&gt;mysql -h tungsten1 -e 'create table mydb3.t1 (i int)'&lt;br /&gt;mysql -h tungsten1 -e 'select seqno,source_id,eventid  from tungsten_logos.trep_commit_seqno'&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;| seqno | source_id | eventid                    |&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;|     6 | tungsten1 | 000002:0000000000000939;43 |&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;&lt;/pre&gt;Everything under control. The master has sent 6 events through the pipeline. Now, let's see what the slave has to say:&lt;br /&gt;&lt;pre&gt;# slave&lt;br /&gt;mysql -h tungsten2 -e 'select seqno,source_id,eventid  from tungsten_logos.trep_commit_seqno'&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;| seqno | source_id | eventid                    |&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;|     0 | tungsten1 | 000002:0000000000000426;34 |&lt;br /&gt;|     0 | tungsten1 | 000002:0000000000000426;34 |&lt;br /&gt;|     4 | tungsten1 | 000002:0000000000000763;41 |&lt;br /&gt;|     5 | tungsten1 | 000002:0000000000000851;42 |&lt;br /&gt;|     6 | tungsten1 | 000002:0000000000000939;43 |&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;&lt;/pre&gt;Notice, at first sight, that there are five rows instead of one. Each row is a channel. Since the master has used three databases, you see three channels occupied, each one showing the latest sequence that was applied. Now, if we do something to database mydb2, we should see one of these channels change, while the others stay still.&lt;br /&gt;&lt;pre&gt;# master&lt;br /&gt;mysql -h tungsten1 -e 'insert into mydb2.t1 values (1)'&lt;br /&gt;mysql -h tungsten1 -e 'insert into mydb2.t1 values (2)'&lt;br /&gt;&lt;br /&gt;# slave&lt;br /&gt;mysql -h tungsten2 -e 'select seqno,source_id,eventid  from tungsten_logos.trep_commit_seqno'&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;| seqno | source_id | eventid                    |&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;|     0 | tungsten1 | 000002:0000000000000426;34 |&lt;br /&gt;|     0 | tungsten1 | 000002:0000000000000426;34 |&lt;br /&gt;|     4 | tungsten1 | 000002:0000000000000763;41 |&lt;br /&gt;&lt;b&gt;|     8 | tungsten1 | 000002:0000000000001124;45 |&lt;/b&gt;&lt;br /&gt;|     6 | tungsten1 | 000002:0000000000000939;43 |&lt;br /&gt;+-------+-----------+----------------------------+&lt;br /&gt;&lt;/pre&gt;The channel used by mydb2 had previously applied the sequence number 5. The latest sequence number was previously 6, used in another channel. After two more events in this database, the sequence number has jumped to 8. &lt;br /&gt;The eventID has also changed. The first part of the eventID is the binary log number (as in mysql-bin.000002), the second is the log position (1124), and the third one is the session ID (45).&lt;br /&gt;Enough of peeking over the replicator's shoulder. There are more tools that let you inspect the status of the operations.&lt;br /&gt;We have seen &lt;code&gt;trepctl services&lt;/code&gt;, which keeps some of its usefulness also with parallel replication. In the master, it says:&lt;br /&gt;&lt;pre&gt;trepctl -host tungsten1 services&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 8&lt;br /&gt;appliedLatency  : 0.834&lt;br /&gt;role            : master&lt;br /&gt;serviceName     : logos&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;&lt;/pre&gt;Which is mostly all we need to know. &lt;br /&gt;Since the slave has more than one channel, though, we need more specialized information on that side of the applier. For this reason, we use a more specialized view. We may start with &lt;code&gt;trepctl status&lt;/code&gt;, which has information that is roughly equivalent to "SHOW SLAVE STATUS" in MySQL native replication.&lt;br /&gt;&lt;pre&gt;trepctl -host tungsten2 status &lt;br /&gt;NAME                     VALUE&lt;br /&gt;----                     -----&lt;br /&gt;appliedLastEventId     : 000002:0000000000000426;34&lt;br /&gt;appliedLastSeqno       : 0&lt;br /&gt;appliedLatency         : 0.846&lt;br /&gt;clusterName            : &lt;br /&gt;currentEventId         : NONE&lt;br /&gt;currentTimeMillis      : 1298626724016&lt;br /&gt;dataServerHost         : tungsten2&lt;br /&gt;extensions             : &lt;br /&gt;host                   : null&lt;br /&gt;latestEpochNumber      : 0&lt;br /&gt;masterConnectUri       : thl://tungsten1:2112/&lt;br /&gt;masterListenUri        : thl://tungsten2:2112/&lt;br /&gt;maximumStoredSeqNo     : 8&lt;br /&gt;minimumStoredSeqNo     : 0&lt;br /&gt;offlineRequests        : NONE&lt;br /&gt;pendingError           : NONE&lt;br /&gt;pendingErrorCode       : NONE&lt;br /&gt;pendingErrorEventId    : NONE&lt;br /&gt;pendingErrorSeqno      : -1&lt;br /&gt;pendingExceptionMessage: NONE&lt;br /&gt;resourcePrecedence     : 99&lt;br /&gt;rmiPort                : -1&lt;br /&gt;role                   : slave&lt;br /&gt;seqnoType              : java.lang.Long&lt;br /&gt;serviceName            : logos&lt;br /&gt;serviceType            : local&lt;br /&gt;simpleServiceName      : logos&lt;br /&gt;siteName               : default&lt;br /&gt;sourceId               : tungsten2&lt;br /&gt;state                  : ONLINE&lt;br /&gt;timeInStateSeconds     : 3483.836&lt;br /&gt;uptimeSeconds          : 3489.47&lt;br /&gt;&lt;/pre&gt;Also this command, which is perfectly useful in single channel replication, lacks the kind of detail that we are after. Tungsten 2.0 introduces two variations of this command, with more detailed metadata.&lt;br /&gt;&lt;pre&gt;trepctl -host tungsten2 status -name tasks&lt;br /&gt;Processing status command (tasks)...&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000001305;46&lt;br /&gt;appliedLastSeqno  : 8&lt;br /&gt;appliedLatency    : 0.84&lt;br /&gt;cancelled         : false&lt;br /&gt;eventCount        : 9&lt;br /&gt;stage             : remote-to-thl&lt;br /&gt;taskId            : 0&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000001305;46&lt;br /&gt;appliedLastSeqno  : 8&lt;br /&gt;appliedLatency    : 0.841&lt;br /&gt;cancelled         : false&lt;br /&gt;eventCount        : 9&lt;br /&gt;stage             : thl-to-q&lt;br /&gt;taskId            : 0&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000000426;34&lt;br /&gt;appliedLastSeqno  : 0&lt;br /&gt;appliedLatency    : 8.422&lt;br /&gt;cancelled         : false&lt;br /&gt;eventCount        : 2&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;taskId            : 0&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000000426;34&lt;br /&gt;appliedLastSeqno  : 0&lt;br /&gt;appliedLatency    : 8.424&lt;br /&gt;cancelled         : false&lt;br /&gt;eventCount        : 1&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;taskId            : 1&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000000763;41&lt;br /&gt;appliedLastSeqno  : 4&lt;br /&gt;appliedLatency    : 0.242&lt;br /&gt;cancelled         : false&lt;br /&gt;eventCount        : 3&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;taskId            : 2&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000001305;46&lt;br /&gt;appliedLastSeqno  : 8&lt;br /&gt;appliedLatency    : 0.846&lt;br /&gt;cancelled         : false&lt;br /&gt;eventCount        : 5&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;taskId            : 3&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000000939;43&lt;br /&gt;appliedLastSeqno  : 6&lt;br /&gt;appliedLatency    : 0.296&lt;br /&gt;cancelled         : false&lt;br /&gt;eventCount        : 3&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;taskId            : 4&lt;br /&gt;&lt;/pre&gt;The &lt;code&gt;-name tasks&lt;/code&gt; command gives you a list of the latest tasks that were happening.&lt;br /&gt;This is probably more information that you want to know about, but in case of troubleshooting it may become a blessing. Let's follow for a moment what's going on to appliedLastSeqno 8. You will find three tasks with this sequance number. The first one has stage "remote-to-thl", which is the stage where the transaction is transported from the master to the &lt;b&gt;T&lt;/b&gt;ransaction &lt;b&gt;H&lt;/b&gt;istory &lt;b&gt;L&lt;/b&gt;ist (THL, which is Tungsten lingo to what you may also call a relay log.). The second task that mentions appliedLastSeqno 8 is in stage "thl-to-q", which is the phase where a transaction is assigned to a given shard. The third occurrence happens in stage "q-to-dbms", which is where the transaction is executed in the slave.&lt;br /&gt;For a different view of what is going on, you may use &lt;code&gt;trepctl status -name shards&lt;/code&gt;. A Shard, in this context, is the criteria used to split the transactions across channels. By default, it happens by database. We will inspect its mechanics more closely in another post. For now, let's have a look at what shards we have in our slave:&lt;br /&gt;&lt;pre&gt;trepctl -host tungsten2 status -name shards&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000000763;41&lt;br /&gt;appliedLastSeqno  : 4&lt;br /&gt;appliedLatency    : 0.0&lt;br /&gt;eventCount        : 2&lt;br /&gt;shardId           : mydb1&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000001305;46&lt;br /&gt;appliedLastSeqno  : 8&lt;br /&gt;appliedLatency    : 0.0&lt;br /&gt;eventCount        : 4&lt;br /&gt;shardId           : mydb2&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000000939;43&lt;br /&gt;appliedLastSeqno  : 6&lt;br /&gt;appliedLatency    : 0.0&lt;br /&gt;eventCount        : 2&lt;br /&gt;shardId           : mydb3&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;NAME                VALUE&lt;br /&gt;----                -----&lt;br /&gt;appliedLastEventId: 000002:0000000000000426;34&lt;br /&gt;appliedLastSeqno  : 0&lt;br /&gt;appliedLatency    : 0.0&lt;br /&gt;eventCount        : 6&lt;br /&gt;shardId           : tungsten_logos&lt;br /&gt;stage             : q-to-dbms&lt;br /&gt;&lt;/pre&gt;You may read the information quite easily. Each shard tells you by which key it was identified (&lt;code&gt;shardID&lt;/code&gt;), and this is the same as the database name. The &lt;code&gt;appliedLastSeqno&lt;/code&gt; and &lt;code&gt;stage&lt;/code&gt; we have met already. The &lt;code&gt;appliedLatency&lt;/code&gt; is roughly equivalent to MySQL's &lt;i&gt;seconds behind master&lt;/i&gt;, but more granular than that. And &lt;code&gt;eventCount&lt;/code&gt; tells you how many transactions went through this shard.&lt;br /&gt;If you are the adventurous type, you may have a look at the THL itself, and get a glimpse of how the replication and the parallelism works.&lt;br /&gt;In the slave, type the following&lt;br /&gt;&lt;pre&gt;# slave&lt;br /&gt;thl -service logos list |less&lt;br /&gt;&lt;/pre&gt;Then look for "SEQ#" and you will find the global transaction IDs, or look for "shard=", and you will see the split by database.&lt;br /&gt;&lt;br /&gt;More goodies will come next week. Until then, happy hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5992067812308065594?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5992067812308065594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5992067812308065594' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5992067812308065594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5992067812308065594'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/02/advanced-replication-for-masses-part-ii.html' title='Advanced replication for the masses - Part II - Parallel replication'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/_gVfZHGgf5LA/TWbezv9WHgI/AAAAAAAABDA/2VhJUDbAIdM/s72-c/Tungsten_parallel_replication.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-2783915973709174823</id><published>2011-02-22T18:47:00.002+01:00</published><updated>2011-02-25T10:03:59.341+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='multi-master'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='advanced'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='clustering'/><category scheme='http://www.blogger.com/atom/ns#' term='parallel'/><title type='text'>Advanced replication for the masses - Part I - Getting started with Tungsten Replicator</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.continuent.com/solutions/tungsten-replicator"&gt;&lt;img alt="Tungsten Replicator" border="0" src="https://lh5.googleusercontent.com/_gVfZHGgf5LA/TWOJnNV9P5I/AAAAAAAABCs/vGQ41Dw-eTE/tungsten_replicator2.png" title="Tungsten replicator" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;MySQL DBAs and developers: oil your fingers and get ready to experience a new dimension of data replication. I am pleased to announce that &lt;a href="http://continuent.com/"&gt;Continuent&lt;/a&gt; has just released &lt;a href="http://www.continuent.com/solutions/tungsten-replicator"&gt;Tungsten Replicator 2.0&lt;/a&gt;, an open source data replication engine that can replace MySQL native replication with a set of advanced features.&lt;br /&gt;&lt;i&gt;A note about the source code. The current version of Tungsten Replicator available in the web site is free to use, but it is not yet the open source version. We need a few weeks more to extract the code from the enterprise tree and make a new build. But we did not want to delay the user experience. So everything that is in this build will come with the source code in a short while. In the meantime, enjoy what is available there and have as much fun as we are having.&lt;/i&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;h3&gt;Why you will want to install Tungsten Replicator 2.0&lt;/h3&gt;Tungsten Replicator has a real cool &lt;a href="http://www.continuent.com/solutions/featurematrix"&gt;list of features&lt;/a&gt;. I am sure that most MySQL DBAs would find something in that list that makes their mouth water in expectation.&lt;br /&gt;Among my favorite features, there is one that looks so innocently non-important that you may be tempted to dismiss it. I am talking about global transaction ID, which is paramount in helping the DBA in switching from master to slave in case of failure or maintenance. I will show an example of a seamless failover in this article.&lt;br /&gt;More things to get excited about: Tungsten allows multiple master replication, i.e. one slave receiving data from several sources, and parallel replication, meaning that a slave can apply changes from the master using many parallel threads. I will talk about all of those features in my blog. But to get to that point, I will need to start by covering the basic installation first. Since Tungsten is much more powerful than MySQL native replication, it also comes with greater complexity. We are working at reducing such complexity. In the meantime, you can start with the instructions that come in this post.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Getting ready&lt;/h3&gt;You will need at least two servers, with Java 1.6, Ruby 1.8, and MySQL 5.1 installed.&lt;br /&gt;You may use your own virtual machines, or spare servers, or you can use a pre-defined VMWare image that you can use with VMware player (or VMware Fusion on Mac).&lt;br /&gt;The following instructions refer to the pre-configured VM. You may skip the initial steps if you are using your own servers.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt; download a pre-configured image&lt;br /&gt;&lt;a href="https://files.continuent.com.s3.amazonaws.com/Tungsten_MySQL_CentOS_5_5_VMWare_Image.7z"&gt;https://files.continuent.com.s3.amazonaws.com/Tungsten_MySQL_CentOS_5_5_VMWare_Image.7z&lt;/a&gt;&lt;br /&gt;Warning: it's 1.5 GB, and it expands to 5.5 GB&lt;/li&gt;&lt;li&gt;Expand the VM&lt;/li&gt;&lt;li&gt;Make a copy of the VM. Change the directory names so that you will refer to them as tungsten_vm1 and tungsten_vm2&lt;/li&gt;&lt;li&gt;launch both VMs&lt;/li&gt;&lt;li&gt;Connect to each VM. User names and password for root are in a .doc file within the VM directory.&lt;/li&gt;&lt;li&gt;Change the hostname of the VMs to tungsten1 and tungsten2 (don't forget to modify /etc/sysconfig/network to make the name sticky)&lt;/li&gt;&lt;li&gt;Update /etc/hosts/ with the IP address and hostname of both servers&lt;/li&gt;&lt;li&gt;Switch to the tungsten user&lt;br /&gt;&lt;pre&gt;su - tungsten&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Create a directory $HOME/replicator&lt;/li&gt;&lt;li&gt;Get the Tungsten package into that directory&lt;br /&gt;&lt;pre&gt;cd replicator&lt;br /&gt;wget https://s3.amazonaws.com/releases.continuent.com/tungsten-replicator-2.0.0.tar.gz&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Get the setup scripts from Tungsten Replicator home .&lt;br /&gt;&lt;pre&gt;wget http://tungsten-replicator.googlecode.com/files/simple_install_master_slave.tar.gz&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;unpack the scripts in $HOME/replicator&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I know this was a long list, but it is not terribly difficult. More difficult would be setting all the above manually. As it is today, all you need to do is running the "set_replication.sh" script and Tungsten will come alive to your server in less than one minute.&lt;br /&gt;To do things properly, you will need to do the same operations on both servers. So, assuming that you have done everything in &lt;i&gt;tungsten1&lt;/i&gt;, you can easily mirror the operations to &lt;i&gt;tungsten2&lt;/i&gt;. The virtual machines come with an already installed public SSH key that makes your installation life easier.&lt;br /&gt;&lt;pre&gt;# in tungsten1&lt;br /&gt;cd $HOME/replicator&lt;br /&gt;ssh tungsten2 mkdir replicator&lt;br /&gt;scp simple_install_master_slave.tar.gz tungsten2:$PWD&lt;br /&gt;scp tungsten-replicator-2.0.0.tar.gz tungsten2:$PWD&lt;br /&gt;ssh tungsten2 'cd replicator; tar -xzf simple_install_master_slave.tar.gz '&lt;br /&gt;&lt;/pre&gt;Now that you have the same set of files in both machines, you can trust the wisdom of the installation files and run:&lt;br /&gt;&lt;pre&gt;# tungsten1&lt;br /&gt;./set_replication.sh&lt;br /&gt;ssh tungsten2 $PWD/set_replication.sh&lt;br /&gt;&lt;/pre&gt;This will start the Tungsten replicator in both servers.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Cleaning up&lt;/h3&gt;The sample scripts come with one that is dedicated to cleaning up. There is a "clear_cluster.sh" script that will remove all test data from the database, sweep the tungsten directory away, leaving your system ready to start afresh. As this is a testing environment, this strategy is not so bad. But be aware of the potentially destructive nature of this script, and don't use it in a production environment.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Under the hood&lt;/h3&gt;Tungsten replicator is a complex piece of software, and it's easy to get lost. So here are a few tips on how to get your bearings.&lt;br /&gt;You will find a log file under $HOME/replicator/tungsten/tungsten-replicator/logs/.&lt;br /&gt;This is quite a noisy log, which is supposed to give the developers all information about what's going on in case of a failure. For newcomers, it is quite intimidating, but we are working at making it easier to read. (&lt;i&gt;Be aware that you may find some references to "tungsten-enterprise" in the logs. Don't let this fact deter you. We are working at splitting the former name associations from the packages, and eventually you will only find references to modules named "tungsten-replicator-something" in the logs.&lt;/i&gt;)&lt;br /&gt;At the end of the installation, you should have seen a line inviting you to modify your path to get the replication tools available at your fingertips. Most notable is &lt;c&gt;trepctl&lt;/c&gt;, the &lt;b&gt;T&lt;/b&gt;ungsten &lt;b&gt;Rep&lt;/b&gt;licator &lt;b&gt;C&lt;/b&gt;on&lt;b&gt;T&lt;/b&gt;ro&lt;b&gt;L&lt;/b&gt;.&lt;br /&gt;Using this tool, you can get some information about the replicator status, and perform administrative tasks. A glimpse at the &lt;a href="http://www.continuent.com/downloads/documentation"&gt;Tungsten Replicator Guide 2.0&lt;/a&gt; will give you an idea of what you can do.&lt;br /&gt;For now, suffices to say that you can use trepctl to get the state of the replicator.&lt;br /&gt;Try, for example, the following:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$ trepctl -host tungsten1 services&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 0&lt;br /&gt;appliedLatency  : 0.933&lt;br /&gt;role            : master&lt;br /&gt;serviceName     : logos&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;&lt;br /&gt;$ trepctl -host tungsten2 services&lt;br /&gt;NAME              VALUE&lt;br /&gt;----              -----&lt;br /&gt;appliedLastSeqno: 0&lt;br /&gt;appliedLatency  : 0.966&lt;br /&gt;role            : slave&lt;br /&gt;serviceName     : logos&lt;br /&gt;serviceType     : local&lt;br /&gt;started         : true&lt;br /&gt;state           : ONLINE&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The most important things here are the "state" field, and the "appliedLastSeqno", which is the global transaction ID that we have mentioned before.&lt;br /&gt;If you create or modify something in the master and issue this command again, you will see that the appliedLastSeqno will increment.&lt;br /&gt;You can get some of this information from the MySQL database, where Tungsten keeps a table with the latest status. You may say that this table is roughly equivalent, at least in principle, to the information in SHOW SLAVE STATUS available with native replication.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$ mysql -h tungsten1 -u tungsten -psecret \&lt;br /&gt;    -e 'select * from tungsten_logos.trep_commit_seqno\G'&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;        task_id: 0&lt;br /&gt;          seqno: 0&lt;br /&gt;         fragno: 0&lt;br /&gt;      last_frag: 1&lt;br /&gt;      source_id: tungsten1&lt;br /&gt;   epoch_number: 0&lt;br /&gt;        eventid: 000002:0000000000000416;102&lt;br /&gt;applied_latency: 0&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;What is this "tungsten_logos' database? It is the database that Tungsten creates for each service that was installed. In this case, 'logos' is the service name contained in this sample installation. If you modify the scripts in both servers, and replace 'logos' with 'ripe_mango', you will see that Tungsten creates a 'tungsten_ripe_mango' database, with the same kind of information.&lt;br /&gt;&lt;br /&gt;The basic principle to acquire before moving to more complex topics is that replication in Tungsten is a collection of &lt;b&gt;services&lt;/b&gt;. While the native MySQL replication is a simple pipeline from master to slave, without deviations, Tungsten implements several pipelines, which you can use one by one or in combination. It looks more complex than necessary, but in reality it makes your planning of complex topologies much easier. Instead of making basic replication more complex, Tungsten adopt the principle of deploying the appropriate pipeline or pipelines for the task.&lt;br /&gt;I leave to &lt;a href="http://scale-out-blog.blogspot.com/"&gt;Robert Hodges&lt;/a&gt;, CEO and main architect of Tungsten, the task of explaining the nuts and bolts.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;A sample of Tungsten power: switching from master to slave&lt;/h3&gt;It is probably too much information already for a blog post, but I would like to leave you with the feeling that you are dealing with an extremely powerful tool.&lt;br /&gt;The instructions below will perform a seamless switch between the master and the slave.&lt;br /&gt;Please follow these steps, but make sure there is no traffic hitting the old master during this time, or you may experience consistency issues:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#first, we tell both servers to stop replicating&lt;br /&gt;$ trepctl -service logos -host tungsten2 offline&lt;br /&gt;$ trepctl -service logos -host tungsten1 offline&lt;br /&gt;&lt;br /&gt;# Now that they are offline, we tell each server its new role&lt;br /&gt;# tungsten2 becomes the new master&lt;br /&gt;$ trepctl -service logos -host tungsten2 setrole -role master &lt;br /&gt;&lt;br /&gt;# and then we tell tungsten1 that it's going to be a slave,&lt;br /&gt;# listening to tungsten2 for data&lt;br /&gt;$ trepctl -service logos -host tungsten1 setrole -role slave -uri thl://tungsten2&lt;br /&gt;&lt;br /&gt;# now we put both servers online with the new instructions&lt;br /&gt;$ trepctl -service logos -host tungsten2 online&lt;br /&gt;$ trepctl -service logos -host tungsten1 online&lt;br /&gt;&lt;br /&gt;# and we check that indeed they are both online with the new roles.&lt;br /&gt;$ trepctl -host tungsten1 services&lt;br /&gt;$ trepctl -host tungsten2 services&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;After this set of instructions, tungsten2 is the master, and if we write to it, we will see the changes replicating to tungsten1.&lt;br /&gt;&lt;br /&gt;That's it for today. In the next articles, we will take a look at parallel replication.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;We want to hear from you&lt;/h3&gt;We have released Tungsten Replicator as open source because we believe this will improve the quality of our product. We are looking for bug reports, cooperation, suggestions, patches, and anything that can make the product better. You can report bugs at &lt;a href="http://code.google.com/p/tungsten-replicator/issues/list"&gt;the project home&lt;/a&gt;.&lt;br /&gt;We are particularly eager to hear about user experience. We are aware that the user interface can be better, and we need some input on this matter from interested users.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;A note about security&lt;/h3&gt;What is described in this article is for testing purposes only. Please use the virtual machines that were mentioned in this article behind a firewall. The VM was designed with friendliness in mind, but as it is, it's far from secure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-2783915973709174823?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/2783915973709174823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=2783915973709174823' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2783915973709174823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2783915973709174823'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/02/advanced-replication-for-masses-part-i.html' title='Advanced replication for the masses - Part I - Getting started with Tungsten Replicator'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/_gVfZHGgf5LA/TWOJnNV9P5I/AAAAAAAABCs/vGQ41Dw-eTE/s72-c/tungsten_replicator2.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-4986610938314115256</id><published>2011-02-14T12:10:00.000+01:00</published><updated>2011-02-14T12:20:50.039+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='detect'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='monitoring'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>How to detect if a MySQL server is an active replication slave</title><content type='html'>Sometimes you know for sure. And sometimes you wonder: Is this server part of a replication system? And, most specifically, is it an active slave?&lt;br /&gt;The completeness of the answer depends on how much visibility you have on the server.&lt;br /&gt;If you can ask the DBA, and possibly have access to the server data directory and configuration file, you can get a satisfactory answer. But if your access is limited to SQL access, things get a bit more complicated.&lt;br /&gt;If you have the SUPER or REPLICATION_CLIENT privilege, then it's easy, at least in the surface.&lt;br /&gt;SHOW SLAVE STATUS will tell you if the slave is running. An empty set means that the server was not configured as a slave.&lt;br /&gt;The answer is not absolute, though. You need to read the output of SHOW SLAVE STATUS to understand if replication is under way.&lt;br /&gt;For example, what is the difference between these two listings?&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;## listing 1&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;               Slave_IO_State: &lt;br /&gt;                  Master_Host: QA1&lt;br /&gt;                  Master_User: tungsten_slave&lt;br /&gt;                  Master_Port: 3306&lt;br /&gt;                Connect_Retry: 60&lt;br /&gt;              Master_Log_File: &lt;br /&gt;          Read_Master_Log_Pos: 4&lt;br /&gt;               Relay_Log_File: QA2-relay-bin.000001&lt;br /&gt;                Relay_Log_Pos: 4&lt;br /&gt;        Relay_Master_Log_File: &lt;br /&gt;             Slave_IO_Running: No&lt;br /&gt;            Slave_SQL_Running: No&lt;br /&gt;              Replicate_Do_DB: &lt;br /&gt;          Replicate_Ignore_DB: &lt;br /&gt;           Replicate_Do_Table: &lt;br /&gt;       Replicate_Ignore_Table: &lt;br /&gt;      Replicate_Wild_Do_Table: &lt;br /&gt;  Replicate_Wild_Ignore_Table: &lt;br /&gt;                   Last_Errno: 0&lt;br /&gt;                   Last_Error: &lt;br /&gt;                 Skip_Counter: 0&lt;br /&gt;          Exec_Master_Log_Pos: 0&lt;br /&gt;              Relay_Log_Space: 106&lt;br /&gt;              Until_Condition: None&lt;br /&gt;               Until_Log_File: &lt;br /&gt;                Until_Log_Pos: 0&lt;br /&gt;           Master_SSL_Allowed: No&lt;br /&gt;           Master_SSL_CA_File: &lt;br /&gt;           Master_SSL_CA_Path: &lt;br /&gt;              Master_SSL_Cert: &lt;br /&gt;            Master_SSL_Cipher: &lt;br /&gt;               Master_SSL_Key: &lt;br /&gt;        Seconds_Behind_Master: NULL&lt;br /&gt;Master_SSL_Verify_Server_Cert: No&lt;br /&gt;                Last_IO_Errno: 0&lt;br /&gt;                Last_IO_Error: &lt;br /&gt;               Last_SQL_Errno: 0&lt;br /&gt;               Last_SQL_Error: &lt;br /&gt;## Listing 2&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;               Slave_IO_State: &lt;br /&gt;                  Master_Host: QA1&lt;br /&gt;                  Master_User: test&lt;br /&gt;                  Master_Port: 3306&lt;br /&gt;                Connect_Retry: 60&lt;br /&gt;              Master_Log_File: &lt;br /&gt;          Read_Master_Log_Pos: 4&lt;br /&gt;               Relay_Log_File: QA2-relay-bin.000001&lt;br /&gt;                Relay_Log_Pos: 4&lt;br /&gt;        Relay_Master_Log_File: &lt;br /&gt;             Slave_IO_Running: No&lt;br /&gt;            Slave_SQL_Running: No&lt;br /&gt;              Replicate_Do_DB: &lt;br /&gt;          Replicate_Ignore_DB: &lt;br /&gt;           Replicate_Do_Table: &lt;br /&gt;       Replicate_Ignore_Table: &lt;br /&gt;      Replicate_Wild_Do_Table: &lt;br /&gt;  Replicate_Wild_Ignore_Table: &lt;br /&gt;                   Last_Errno: 0&lt;br /&gt;                   Last_Error: &lt;br /&gt;                 Skip_Counter: 0&lt;br /&gt;          Exec_Master_Log_Pos: 0&lt;br /&gt;              Relay_Log_Space: 125&lt;br /&gt;              Until_Condition: None&lt;br /&gt;               Until_Log_File: &lt;br /&gt;                Until_Log_Pos: 0&lt;br /&gt;           Master_SSL_Allowed: No&lt;br /&gt;           Master_SSL_CA_File: &lt;br /&gt;           Master_SSL_CA_Path: &lt;br /&gt;              Master_SSL_Cert: &lt;br /&gt;            Master_SSL_Cipher: &lt;br /&gt;               Master_SSL_Key: &lt;br /&gt;        Seconds_Behind_Master: NULL&lt;br /&gt;Master_SSL_Verify_Server_Cert: No&lt;br /&gt;                Last_IO_Errno: 0&lt;br /&gt;                Last_IO_Error: &lt;br /&gt;               Last_SQL_Errno: 0&lt;br /&gt;               Last_SQL_Error: &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;They look almost the same, and yet the similarity is deceiving. The first listing is what you get immediately after a call to CHANGE MASTER TO. If you run START SLAVE at this point, replication will start flowing.&lt;br /&gt;The second listing is what you get immediately after a call to RESET SLAVE. The crucial difference is that RESET SLAVE removes the two .info files containing replication credentials and positions. A call to START SLAVE in this scenario will only get you an error, as the slave does not know where and how to connect.&lt;br /&gt;So, in this case, SQL visibility does only tell you that the server is not receiving replication date, and that it was at least once configured as a slave. The telltale detail is the user name ("test") that should give you a hint of something fishy going on. Unless you have called your user "test", in which case you were asking for trouble. I would say that this situation is a bug. RESET SLAVE should remove every memory of the slave configuration, and instead it keeps only the host name. Although it is not clear in this particular example, it also forgets the master connection port. &lt;br /&gt;&lt;br /&gt;Now, if your purpose was to set replication with different coordinates, the good news is that in both cases a well formed call &lt;small&gt;&lt;sup&gt;(*)&lt;/sup&gt;&lt;/small&gt; to CHANGE MASTER TO will do what you expect, i.e. it will establish the credentials to the master, so that a further invocation of START SLAVE will let replication data flow.&lt;br /&gt;&lt;br /&gt;&lt;small&gt;&lt;sup&gt;(*)&lt;/sup&gt; By "well formed" I mean a call that includes host, port, username, password, binary log file and position, and eventually all the information that you need to get the slave at work. &lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-4986610938314115256?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/4986610938314115256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=4986610938314115256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4986610938314115256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4986610938314115256'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/02/how-to-detect-if-mysql-server-is-active.html' title='How to detect if a MySQL server is an active replication slave'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5527957738323690150</id><published>2011-02-08T23:36:00.000+01:00</published><updated>2011-02-08T23:36:22.716+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xtrabackup'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='webinar'/><category scheme='http://www.blogger.com/atom/ns#' term='percona'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='backup'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='speaking'/><title type='text'>Webinar: Percona and Continuent on backup and replication with huge data</title><content type='html'>On Thursday, February 10, at 10am PST, there is a free webinar about &lt;a href="https://www1.gotomeeting.com/register/911691169"&gt;Managing Big Data with Percona Server, XtraBackup and Tungsten&lt;/a&gt;. Quoting from the announcement:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;&lt;br /&gt;Big data is a big problem for growing SaaS businesses and large web applications.  In this webinar, we'll teach you how to set up Percona Server, XtraBackup, and Tungsten to manage Terabyte+ databases and scale to millions of transactions a day.  We'll discuss the latest features for high transaction performance like InnoDB buffer pool dump/restore and HandlerSocket, our favorite tricks for backup, restore, and provisioning of large data sets, and how to replicate scalably and safely using Tungsten Replicator with parallel apply.  &lt;br /&gt;&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;The presenters are representatives of both &lt;a href="http://percona.com/"&gt;Percona&lt;/a&gt; and &lt;a href="http://continuent.com/"&gt;Continuent&lt;/a&gt;, &lt;br /&gt;Vadim Tkachenko, Percona Co-Founder &amp;amp; CTO, &lt;br /&gt;Robert Hodges, Continuent CEO&lt;br /&gt;Edward Archibald, Continuent CTO&lt;br /&gt;&lt;br /&gt;The event will showcase Xtrabackup and Tungsten features in an interesting combined view.&lt;br /&gt;The event is free, but &lt;a href="https://www1.gotomeeting.com/register/911691169"&gt;registration&lt;/a&gt; is required.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5527957738323690150?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5527957738323690150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5527957738323690150' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5527957738323690150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5527957738323690150'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/02/webinar-percona-and-continuent-on.html' title='Webinar: Percona and Continuent on backup and replication with huge data'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-8773454917938411524</id><published>2011-02-07T19:00:00.003+01:00</published><updated>2011-02-07T21:57:13.536+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='metadata'/><category scheme='http://www.blogger.com/atom/ns#' term='information_schema'/><category scheme='http://www.blogger.com/atom/ns#' term='performance_schema'/><category scheme='http://www.blogger.com/atom/ns#' term='binaries'/><title type='text'>Evolution of MySQL metadata</title><content type='html'>I was looking at the latest MySQL versions, and I happened to notice that there has been a great increment in the number of metadata tables, both in the information_schema and performance_schema databases. So I made a simple count of both schemas in the various versions, and draw a graph. The advance looks straightforward.&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellpadding="5" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;version&lt;/th&gt;&lt;th&gt;Information_schema&lt;/th&gt;&lt;th&gt;performance_schema&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5.0.92&lt;/td&gt;&lt;td align="right"&gt;17&lt;/td&gt;&lt;td align="right"&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5.1.54&lt;/td&gt;&lt;td align="right"&gt;28&lt;/td&gt;&lt;td align="right"&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5.1.54 with innodb plugin&lt;/td&gt;&lt;td align="right"&gt;35&lt;/td&gt;&lt;td align="right"&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5.5.8&lt;/td&gt;&lt;td align="right"&gt;37&lt;/td&gt;&lt;td align="right"&gt;17&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5.6.2&lt;/td&gt;&lt;td align="right"&gt;48&lt;/td&gt;&lt;td align="right"&gt;23&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;img src="https://lh4.googleusercontent.com/_gVfZHGgf5LA/TVBcO4gcsSI/AAAAAAAABCI/aFPpmChTqN4/IS_PS_graph.png" title="Information_schema tables and performance_schema evolution" /&gt;&lt;br /&gt;&lt;br /&gt;The difference between 5.0 and 5.6 is staggering. We came from 17 to 71 metadata total tables. A stacked bar chart helps visualize the changes.&lt;br /&gt;&lt;br /&gt;&lt;img src="https://lh4.googleusercontent.com/_gVfZHGgf5LA/TVBcPMtvA_I/AAAAAAAABCM/22GgDJ94LL4/IS_PS_graph_stacked.png" title="Information_schema tables and performance_schema evolution" /&gt;&lt;br /&gt;&lt;br /&gt;I noticed, BTW, that &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/news-5-0-92.html%22"&gt;MySQL 5.0.92&lt;/a&gt;, which is not in active support, was released without the binaries for Mac OSX. If this kind of edition is limited to the versions in extended support, that's fine with me. I hope the habit does not contaminate the regular builds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-8773454917938411524?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/8773454917938411524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=8773454917938411524' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8773454917938411524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8773454917938411524'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/02/evolution-of-mysql-metadata.html' title='Evolution of MySQL metadata'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/_gVfZHGgf5LA/TVBcO4gcsSI/AAAAAAAABCI/aFPpmChTqN4/s72-c/IS_PS_graph.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-2759056779859093685</id><published>2011-02-03T12:13:00.000+01:00</published><updated>2011-02-03T12:13:25.260+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='opendatabasecamp'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='ingres'/><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='opensqlcamp'/><category scheme='http://www.blogger.com/atom/ns#' term='camp'/><category scheme='http://www.blogger.com/atom/ns#' term='sardinia'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Open Database Camp - Accommodation and Sponsoring</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://opensqlcamp.org/Events/Sardinia2011/Sponsors"&gt;&lt;img alt="Sponsoring Open Database Camp" border="0" src="https://lh4.googleusercontent.com/_gVfZHGgf5LA/TUqBzt9LGiI/AAAAAAAABBs/tQrS1lj1JXI/opendbcamp_sponsoring.png" title="Sponsoring Open Database Camp 2011" width="250" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;br /&gt;The &lt;a href="http://opendbcamp.org/"&gt;Open Database Camp 2011&lt;/a&gt; is shaping up nicely.&lt;br /&gt;The logistics is being defined and local and international volunteers are showing up for help. (Thanks, folks!)&lt;br /&gt;If you want to start booking, there is a list of hotels in the &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/Accommodation"&gt;Accommodation page&lt;/a&gt;.&lt;br /&gt;And don't forget to sign up in the &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/AttendeeList"&gt;Attendees list&lt;/a&gt;.&lt;br /&gt;Local travel information will be released as soon as we finish cranking up the plan.&lt;br /&gt;Open Database camp is free, but we still have expenses to get the job done. &lt;br /&gt;We need both official sponsors and personal donations. No minimum amount required. You can donate painlessly online through the nonprofit organization &lt;a href="http://technocation.org/"&gt;Technocation.&lt;/a&gt; (Thanks!)&lt;br /&gt;Please see the &lt;a href="http://opensqlcamp.org/Events/Sardinia2011/Sponsors"&gt;Sponsors page&lt;/a&gt; for more info. &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-2759056779859093685?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/2759056779859093685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=2759056779859093685' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2759056779859093685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2759056779859093685'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/02/open-database-camp-accommodation-and.html' title='Open Database Camp - Accommodation and Sponsoring'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/_gVfZHGgf5LA/TUqBzt9LGiI/AAAAAAAABBs/tQrS1lj1JXI/s72-c/opendbcamp_sponsoring.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-2276785366454591199</id><published>2011-01-30T20:09:00.001+01:00</published><updated>2011-01-30T20:49:54.279+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='master'/><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='5.6'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='slave'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='delayed'/><title type='text'>A first look at delayed replication in MySQL 5.6</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://forge.mysql.com/worklog/task.php?id=344"&gt;&lt;img alt="Delayed replication" border="0" src="https://lh3.googleusercontent.com/_gVfZHGgf5LA/TUWrNQRopwI/AAAAAAAABBc/xYBHwmaAalg/delayed_replication.png" title="Delayed replication" width="300" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;If you like fresh features, you should not miss this one. MySQL 5.6.2 includes, among other improvements, the implementation of &lt;a href="http://forge.mysql.com/worklog/task.php?id=344"&gt;Time delayed replication&lt;/a&gt;, a feature that lets you tell the slave not to apply changes from the master immediately, but to wait N seconds.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The feature is documented in &lt;a href="http://forge.mysql.com/worklog/task.php?id=344"&gt;WL#344&lt;/a&gt;. (There was a manual online as well together with the binaries for MySQL 5.6.0, but they were removed after a few days for a good reason. I am confident that both the manual and some binaries will eventually show up soon).&lt;br /&gt;Since as of today there are no binaries for MySQL 5.6.x, you need to get the code and compile it yourself. Just get the code from &lt;a href="https://code.launchpad.net/mysql-server"&gt;https://code.launchpad.net/mysql-server&lt;/a&gt; and compile it using the instructions in &lt;a href="http://datacharmer.blogspot.com/2010/04/building-mysql-55-with-cmake.html"&gt;building MySQL 5.5 with cmake&lt;/a&gt;.&lt;br /&gt;To get a taste of this new feature, the quickest way is to set up replication using the binaries that you have built and &lt;a href="http://mysqlsandbox.net/"&gt;MySQL Sandbox&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;make_replication_sandbox  mysql-5.6.2-m5-osx10.6-.tar.gz &lt;br /&gt;# the file name may change, depending on the operating system you are using&lt;br /&gt;&lt;/pre&gt;Soon you will have one master and two slaves in $HOME/sandboxes/rsandbox_5_6_2.&lt;br /&gt;What you have to do is connect to one of the slaves and enter these commands:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;STOP SLAVE;&lt;br /&gt;change master to &lt;b&gt;master_delay=60&lt;/b&gt;;&lt;br /&gt;START SLAVE;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Let's say that you did this to slave #2.&lt;br /&gt;Now whatever you do in the master will be replicated immediately in slave #1, but it will executed with 60 seconds delay in slave #2.&lt;br /&gt;To be clear, the IO_THREADs of both slaves keep getting data from the master as fast as they can, same as they did until version 5.5, but slave #2 will hold the SQL_THREAD for the defined amount of seconds.&lt;br /&gt;This new state is visible in the output of the SHOW SLAVE STATUS command, which lists this information after you do something in the master like creating a table or inserting data:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;               SQL_Delay: 60&lt;br /&gt;     SQL_Remaining_Delay: 43&lt;br /&gt; Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The main purpose of delayed replication is to protect the server against human mistakes. If I accidentally drop a table, the statement is instantly replicated to all the slaves, but it is not executed to the delayed slaves.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$ ./m -e 'drop table test.t1 '&lt;br /&gt;$ ./use_all 'show tables from test'&lt;br /&gt;# master  &lt;br /&gt;# server: 1: &lt;br /&gt;# server: 2: &lt;br /&gt;Tables_in_test&lt;br /&gt;t1&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The table is gone in the master, and it is gone in the regular slave, but it is still there in the delayed slave. And if I detect the problem before the delayed statement gets executed (a delay time longer than 60 seconds would be advisable in this case, 3600=1 hour, seems healthier), then I may be able to recover the data.&lt;br /&gt;&lt;br /&gt;I notice en passant that there is much more than delayed replication going on in MySQL 5.6. For example, the information_schema tables related to InnoDB have increased from 7 to 18:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; show tables from information_schema like 'innodb%';&lt;br /&gt;+----------------------------------------+&lt;br /&gt;| Tables_in_information_schema (innodb%) |&lt;br /&gt;+----------------------------------------+&lt;br /&gt;| INNODB_CMPMEM                          |&lt;br /&gt;| INNODB_TRX                             |&lt;br /&gt;| INNODB_BUFFER_PAGE                     | *&lt;br /&gt;| INNODB_LOCK_WAITS                      |&lt;br /&gt;| INNODB_SYS_TABLESTATS                  | *&lt;br /&gt;| INNODB_CMP                             |&lt;br /&gt;| INNODB_SYS_COLUMNS                     | *&lt;br /&gt;| INNODB_CMPMEM_RESET                    |&lt;br /&gt;| INNODB_SYS_FOREIGN_COLS                | *&lt;br /&gt;| INNODB_BUFFER_PAGE_LRU                 | * &lt;br /&gt;| INNODB_BUFFER_POOL_STATS               | *&lt;br /&gt;| INNODB_CMP_RESET                       |&lt;br /&gt;| INNODB_SYS_FOREIGN                     | *&lt;br /&gt;| INNODB_METRICS                         | *&lt;br /&gt;| INNODB_SYS_INDEXES                     | *&lt;br /&gt;| INNODB_LOCKS                           |&lt;br /&gt;| INNODB_SYS_FIELDS                      | *&lt;br /&gt;| INNODB_SYS_TABLES                      | *&lt;br /&gt;+----------------------------------------+&lt;br /&gt;18 rows in set (0.00 sec)&lt;br /&gt;# (*) new tables marked with a star&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;What they do and how to play with them will be matter for some more investigation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-2276785366454591199?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/2276785366454591199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=2276785366454591199' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2276785366454591199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2276785366454591199'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/01/first-look-at-delayed-replication-in.html' title='A first look at delayed replication in MySQL 5.6'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/_gVfZHGgf5LA/TUWrNQRopwI/AAAAAAAABBc/xYBHwmaAalg/s72-c/delayed_replication.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1964245034746406070</id><published>2011-01-28T21:01:00.000+01:00</published><updated>2011-01-28T21:01:17.813+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IOUG'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='council'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>The MySQL Council is up and running. We want to hear from you!</title><content type='html'>The &lt;b&gt;I&lt;/b&gt;ndependent &lt;b&gt;O&lt;/b&gt;racle &lt;b&gt;U&lt;/b&gt;ser &lt;b&gt;G&lt;/b&gt;roup (IOUG) has formed the &lt;a href="http://www.ioug.org/Events/IOUGWelcomesMySQL/tabid/164/Default.aspx"&gt;MySQL Council&lt;/a&gt;, with the purpose of addressing the interests and needs of MySQL users.&lt;br /&gt;&lt;br /&gt;The current Council members are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sarah Novotny, Blue Gecko, Council Chair&lt;/li&gt;&lt;li&gt;Sheeri Cabral, PalominoDB&lt;/li&gt;&lt;li&gt;Bradley Kuszmaul, Tokutek&lt;/li&gt;&lt;li&gt;Giuseppe Maxia, Continuent&lt;/li&gt;&lt;li&gt;Rob Wultsch, GoDaddy.com&lt;/li&gt;&lt;li&gt;Matt Yonkovit, Percona &lt;/li&gt;&lt;/ul&gt;The IOUG is a well established and respected institution, with more than 20,000 database professionals registered as its members. In the long history of Oracle, the IOUG has always played a role in the aftermath of many acquisitions, extending a friendly hand to the newcomers in the family. I have spent much time with IOUG people, and I was impressed by their enthusiasm and professionalism. My impression of the IOUG is that it is a friendly group of people with the common goal of improving the experience of being an Oracle user.&lt;br /&gt;The IOUG is not looking for assimilation. While Oracle business strategy calls for full integration, the IOUG recognizes that users come in different sizes and shapes, and they cannot be forced into the institution. Instead, the IOUG want to understand the newcomers and offer their services to help out towards the common goals. The IOUG people also know that many old Oracle users are also MySQL users. By facilitating the integration of the MySQL community they are serving the needs of a wider population than the traditional set of MySQL users.&lt;br /&gt;&lt;br /&gt;The MySQL community has never been organized as a whole. There id nothing comparable to the massive presence of the Oracle user group. MySQL users are mostly isolated. When they convene into social entities, they identify themselves either by town boundaries or by being member of some group that has some interest in MySQL (Linux distributions, PHP developers, CMS framework users). There is no unified view of what users represent or want, and a difficult dialog between the user base and the company that produces the software. &lt;br /&gt;With Oracle, this lack of unity is yet another obstacle in the path to a good understanding. Oracle is used to talk to a large entity representing its users, and it has not the patience or the skills to deal with such a distributed presence as the MySQL community. For this reason I believe that the MySQL Council is a good idea. It provides a tool for the will of the MySQL community to be conveyed to the company, using the IOUG, one of the channels that are familiar to Oracle, and that are more likely to reach the decision makers. &lt;br /&gt;&lt;br /&gt;The main goal of the council should be to mend fences. There is much to be done. The culture of traditional Oracle users and that of MySQL users are different and sometimes hard to reconcile. Oracle strategies that were tuned towards pleasing their traditional customers may not suit the needs of the newcomers. All this needs to be addressed, and the MySQL Council could be the first step to the solution.&lt;br /&gt;&lt;br /&gt;For this reason, the council members want to hear from the community. What are the main pain points and issues that you want addressed? What is Oracle doing right with MySQL? Where could it improve?&lt;br /&gt;&lt;br /&gt;If you know one or more of us, please contact us by email. Or write a blog post about the issues to address. Or comment in our blogs. We want to hear from you. We feel that we must represent the larger MySQL community and bridge the gaps between the company and the user base.&lt;br /&gt;&lt;br /&gt;The roles of the MySQL Council is not only to be a diplomatic channel of communication between users and company. It will also help with the diffusion of MySQL culture among Oracle users, with articles, conferences, meetings, and whatever the imagination provides to achieve the goal of spreading the word.&lt;br /&gt;&lt;br /&gt;Also for this goal we welcome your input. Make your voice heard. It's time to boost the technical writing in Planet MySQL and in the rest of the net. Let MySQL be known!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1964245034746406070?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1964245034746406070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1964245034746406070' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1964245034746406070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1964245034746406070'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/01/mysql-council-is-up-and-running-we-want.html' title='The MySQL Council is up and running. We want to hear from you!'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-8079554901979578844</id><published>2011-01-25T16:20:00.000+01:00</published><updated>2011-01-25T16:20:16.816+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='ACE'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Joining the Oracle ACE program</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.oracle.com/technetwork/community/oracle-ace/index.html"&gt;&lt;img alt="Ace charmer" border="0" src="http://lh5.ggpht.com/_gVfZHGgf5LA/TT7pnx5vEAI/AAAAAAAABBM/-nhXnNVrd1U/datacharmer_ace.png" title="The Ace Charmer" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;A few days ago I received an invitation to join the &lt;a href="http://www.blogger.com/%20http://www.oracle.com/technetwork/community/oracle-ace/index.html"&gt;Oracle ACE program&lt;/a&gt;, which is a group of strong community enthusiasts and advocate of Oracle products.&lt;br /&gt;Since I have been a vocal member of the MySQL community for years, I welcome this acknowledgment as well as I appreciated being nominated MySQL Community Contributor of the Year in 2006. Unlike that award, which came from inside the MySQL company, the Oracle ACE nomination came from my peers in the community, to whom I address my thanks and appreciation. &lt;br /&gt;The nomination comes from the community, but the title is granted by the company, as recognition for good work. Therefore, thanks also to my former colleagues at Oracle who have approved my current status.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;For the ones who are curious, being an Oracle ACE does not mean becoming an employee, or &lt;a href="http://www.oracle.com/technetwork/community/oracle-ace-faq-100746.html#4"&gt;having obligations towards Oracle&lt;/a&gt;. There is not even an obligation to be kind towards the company, meaning that Oracle ACEs can be as outspoken as they feel they should. So, there is no restraint on what I can tell in public, and no expectations of unconditional support for Oracle policies.&lt;br /&gt;What you can expect is for me to be my usual self, the guy who is enthusiast about cool technology, no matter where it comes from, and critical or appreciative depending on merit. &lt;br /&gt;Now, back to hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-8079554901979578844?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/8079554901979578844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=8079554901979578844' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8079554901979578844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/8079554901979578844'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/01/joining-oracle-ace-program.html' title='Joining the Oracle ACE program'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_gVfZHGgf5LA/TT7pnx5vEAI/AAAAAAAABBM/-nhXnNVrd1U/s72-c/datacharmer_ace.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-756232640626239871</id><published>2011-01-22T21:58:00.003+01:00</published><updated>2011-01-22T22:43:49.604+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stored procedures'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='stored routines'/><category scheme='http://www.blogger.com/atom/ns#' term='lock'/><category scheme='http://www.blogger.com/atom/ns#' term='update'/><category scheme='http://www.blogger.com/atom/ns#' term='monitoring'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Pitfalls of monitoring MySQL table activity with stored routines</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://dev.mysql.com/doc/refman/5.5/en/stored-program-restrictions.html"&gt;&lt;img alt="monitoring tables" border="0" src="http://lh5.ggpht.com/_gVfZHGgf5LA/TTsXDUJw8SI/AAAAAAAABBE/X-Cpv_qRjq0/monitoring_tables.png" title="Monitoring tables" width="300" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;A friend of mine needed a quick method to monitor a table that was frequently updated. There were several procedures writing to the table several times per second. He needed a quick way of determining how many updates per second the table was getting.&lt;br /&gt;The table has only one row, which includes a counter that is increased at each operation. Therefore, the simple plan was:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Let's get the counter from the table;&lt;/li&gt;&lt;li&gt;Allow N seconds to pass;&lt;/li&gt;&lt;li&gt;Get the counter again;&lt;/li&gt;&lt;li&gt;The difference between the second counter and the first counter, divided by the number of seconds gives the updates per second.&lt;/li&gt;&lt;/ol&gt;The plan makes sense, and if you run the above commands manually, you get what you want.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;However, my friend wanted the update ratio to be a single operation, say like:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;SELECT update_ratio();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;He went to make a simple function, following the four steps described above.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;delimiter //&lt;br /&gt;drop function if exists update_ratio //&lt;br /&gt;create function update_ratio()&lt;br /&gt;RETURNS INT &lt;br /&gt;begin&lt;br /&gt;     declare sleep_wait int default 5;&lt;br /&gt;     declare start int default 1;&lt;br /&gt;     declare finish int default 1;&lt;br /&gt;&lt;br /&gt;     set start = (select counter from mytable);&lt;br /&gt;     do sleep(sleep_wait);&lt;br /&gt;     set finish = (select counter from mytable);&lt;br /&gt;     return (finish-start)/sleep_wait;&lt;br /&gt;end $$&lt;br /&gt;delimiter ;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;It seems OK. The function runs without errors, but &lt;b&gt;it always returns zero&lt;/b&gt;.&lt;br /&gt;Mystery! Running the statements manually gives always a sensible result. Using triggers to monitor the table shows that indeed it is updated many times per second, but the function returns always zero.&lt;br /&gt;More puzzling is the fact that if we convert the function to a procedure, it gives the wanted result.&lt;br /&gt;&lt;br /&gt;The solution to the mystery is found in the &lt;a href="http://dev.mysql.com/doc/refman/5.5/en/stored-program-restrictions.html"&gt;MySQL online manual&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;&lt;br /&gt;A stored function acquires table locks before executing, to avoid inconsistency in the binary log due to mismatch of the order in which statements execute and when they appear in the log. &lt;br /&gt;&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;In other words, it means that all tables referenced in a stored functions are locked when the function starts. Therefore the external procedures that were updating the table will have to wait until the function's end before updating. When the function reads from the table, it gets always the same record counter, because no updates were happening in the meantime. That's why the second read is the same as the first one, and the result is zero.&lt;br /&gt;&lt;br /&gt;What should you do then?&lt;br /&gt;One option is to convert the function into a procedure:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;delimiter //&lt;br /&gt;drop procedure if exists show_update_ratio //&lt;br /&gt;create procedure show_update_ratio()&lt;br /&gt;begin&lt;br /&gt;     declare sleep_wait int default 5;&lt;br /&gt;     declare start int default 1;&lt;br /&gt;     declare finish int default 1;&lt;br /&gt;    &lt;br /&gt;     select counter into start from mytable;&lt;br /&gt;     do sleep(sleep_wait);&lt;br /&gt;     select counter into finish from mytable;&lt;br /&gt;     SET @UPS := (finish-start)/sleep_wait;&lt;br /&gt;end //&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;That gets the job done. If you want to get the result into a variable, you can do it with two statements. &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;call show_update_ratio();&lt;br /&gt;select @UPS;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;If you don't change the last SET into a SELECT and just display the value.&lt;br /&gt;&lt;br /&gt;Another option is using several SQL commands from your application. Also in this case, make sure that you are &lt;b&gt;NOT&lt;/b&gt; wrapping this code inside a transaction, or you will get the same result in both queries&lt;br /&gt;&lt;pre&gt;# WRONG!&lt;br /&gt;     set autocommit=0;&lt;br /&gt;     BEGIN;&lt;br /&gt;     select counter into @start from mytable;&lt;br /&gt;     set @start = start;&lt;br /&gt;     do sleep(5);&lt;br /&gt;     select counter into @finish from mytable;&lt;br /&gt;     select (@finish - @start) / 5 as UPS;&lt;br /&gt;&lt;/pre&gt;If you go for this solution (or even the stored procedure), make sure that you are either using autocommit, or commit after each query if you must use a transaction.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-756232640626239871?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/756232640626239871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=756232640626239871' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/756232640626239871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/756232640626239871'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/01/pitfalls-of-monitoring-mysql-table.html' title='Pitfalls of monitoring MySQL table activity with stored routines'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_gVfZHGgf5LA/TTsXDUJw8SI/AAAAAAAABBE/X-Cpv_qRjq0/s72-c/monitoring_tables.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-4001677020717374226</id><published>2011-01-10T13:03:00.000+01:00</published><updated>2011-01-10T13:03:43.355+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hiring'/><category scheme='http://www.blogger.com/atom/ns#' term='qa'/><category scheme='http://www.blogger.com/atom/ns#' term='sontinuent'/><category scheme='http://www.blogger.com/atom/ns#' term='careers'/><category scheme='http://www.blogger.com/atom/ns#' term='support'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='jobs'/><title type='text'>Continuent is hiring - Support and QA engineers wanted</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.continuent.com/about/careers"&gt;&lt;img alt="Continuent is hiring" border="0" src="http://lh4.ggpht.com/_gVfZHGgf5LA/TSrtsdlo2ZI/AAAAAAAABAs/GEifjXyrCE0/continuent_phone_hiring_250_450.png" title="continuent is hiring" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;a href="http://continuent.com/"&gt;Continuent&lt;/a&gt; is &lt;a href="http://www.continuent.com/about/careers"&gt;hiring&lt;/a&gt;. The business is growing, the opportunities are piling up nicely, and we need to beef up the team with the addition of some new professionals. &lt;br /&gt;The mist urgent posts to fill are a &lt;br /&gt;&lt;a href="http://www.continuent.com/about/careers/970-database-clustering-qa-engineer"&gt; QA Engineer&lt;/a&gt; and a &lt;a href="http://www.continuent.com/about/careers/971-database-clustering-support-engineer"&gt;Support Engineer&lt;/a&gt;, both experts of their specific trades and of database clustering. &lt;br /&gt;We are looking at the matter without borders. Although it would be preferable to find  candidates in the US, and in the West Coast in particular, we are really looking for the best people in the market, regardless of their location. &lt;br /&gt;Both jobs are challenging, they are both MySQL related, and both require experience with QA and support respectively, in addition to development background.&lt;br /&gt;If you are a super star in either QA or support, contact &lt;b&gt;resumes AT continuent DOT com&lt;/b&gt;. Also, feel free to contact me, should you need further information.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-4001677020717374226?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/4001677020717374226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=4001677020717374226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4001677020717374226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4001677020717374226'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/01/continuent-is-hiring-support-and-qa.html' title='Continuent is hiring - Support and QA engineers wanted'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_gVfZHGgf5LA/TSrtsdlo2ZI/AAAAAAAABAs/GEifjXyrCE0/s72-c/continuent_phone_hiring_250_450.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-4851218770932306756</id><published>2011-01-06T00:35:00.000+01:00</published><updated>2011-01-06T00:35:09.771+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='innodb'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Announcing the Open Database Camp - Sardinia, May 2011</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://opensqlcamp.org/"&gt;&lt;img alt="Open Database Camp 2011" border="0" src="http://lh4.ggpht.com/_gVfZHGgf5LA/TSTzfrsx8_I/AAAAAAAABAg/XRCbqqZEYPM/open_database_sardinia.png" title="Open Database Camp - Sardinia 2011" width="250" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;I have been traveling to many conferences in the last 10 years, and many times I have been asked to organize an event in my native land, &lt;a href="http://en.wikipedia.org/wiki/Sardinia"&gt;Sardinia&lt;/a&gt;. After delaying the inevitable for long time, here I can announce it. The Open Database Camp 2011 will take place in Sardinia, hosted by the &lt;a href="http://www.sardegnaricerche.it/en/technologypark/"&gt;Sardinia Technology Park&lt;/a&gt;, a local scientific and business institution with international links.&lt;br /&gt;&lt;b&gt;Mark your calendars&lt;/b&gt;: the Open Database Camp will be held in Sardinia on &lt;b&gt;May 6-7-8, 2011&lt;/b&gt;.&lt;br /&gt;I have already confirmed the venue, and I will have full cooperation from Sardegna Ricerche about the conference logistics. I will meet the organizers on January 27th to get in touch with nearby hotels and restaurants and negotiate rates. &lt;br /&gt;The place is a &lt;a href="http://www.sardegnaricerche.it/immagini/13_116_20081008134757.jpg"&gt;beautiful and modern compound&lt;/a&gt;, built in the middle of a forest. About 40 Km from Cagliari and its airport. There is a public bus service to reach the venue, and there will be an integrative bus during the conference.&lt;br /&gt;The place is a few kilometers from the sea resort of Pula, near the archeological beauty of &lt;a href="http://www.google.com/images?q=Nora,+sardinia"&gt;Nora&lt;/a&gt;.  &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;If you want to start booking your flights, look for connections to &lt;a href="http://en.wikipedia.org/wiki/Cagliari"&gt;Cagliari Elmas&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There are cheap direct flights from several European airports with &lt;a href="http://www.easyjet.com/"&gt;EasyJet&lt;/a&gt;, &lt;a href="http://ryanair.com/"&gt;Ryanair&lt;/a&gt;, &lt;a href="http://www.tuifly.com/en/"&gt;TUIFly&lt;/a&gt;, &lt;a href="http://www.airberlin.com/"&gt;Air Berlin&lt;/a&gt;, and probably a few more.&lt;br /&gt;For example, you can fly to Cagliari from Paris, Frankfurt, Berlin, Cologne, Munich, Stuttgart, London, Edinburgh, Brussels, Madrid, Barcelona, Seville, Valencia, Venice, Rome, Milan, Turin, Basel, Geneva, Krakow, and probably more by the time you come.&lt;br /&gt;If you book now, you should be able to get a good price.&lt;br /&gt;&lt;br /&gt;The weather in Sardinia is mild. May is almost summertime. If you live in cold places like the North of the USA, Canada, Scandinavia, May in Sardinia is definitely warmer.&lt;br /&gt;More logistics information will come.&lt;br /&gt;&lt;br /&gt;Why &lt;i&gt;Open Database Camp&lt;/i&gt;, and not &lt;i&gt;Open SQL Camp&lt;/i&gt; like before?&lt;br /&gt;The &lt;a href="http://opensqlcamp.org/"&gt;Open SQL Camp&lt;/a&gt; tradition has evolved since its inception in 2008. It has now become a gathering of database professionals and enthusiasts, not necessarily identifiable with the SQL constraint. &lt;br /&gt;So, the conference welcomes everyone who deals with open databases, regardless of the languages used to interface them.&lt;br /&gt;&lt;br /&gt;Stay tuned for more info. In the meantime, you can discuss this matter in the &lt;a href="http://groups.google.com/group/opensqlcamp"&gt;opensqlcamp Google Group&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-4851218770932306756?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/4851218770932306756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=4851218770932306756' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4851218770932306756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/4851218770932306756'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2011/01/announcing-open-database-camp-sardinia.html' title='Announcing the Open Database Camp - Sardinia, May 2011'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_gVfZHGgf5LA/TSTzfrsx8_I/AAAAAAAABAg/XRCbqqZEYPM/s72-c/open_database_sardinia.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-3896130790240444415</id><published>2010-12-20T23:20:00.000+01:00</published><updated>2010-12-20T23:20:56.306+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='binary log'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Looking for a hack - Passing comment-like info through the binary log</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://datacharmer.org/"&gt;&lt;img alt="hacker" border="0" src="http://lh4.ggpht.com/_gVfZHGgf5LA/TQ_L1p1yldI/AAAAAAAAA_4/77FLiXP99Lg/hack1_no_bg_300px.jpg" title="hacker" width="200" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;I am facing an interesting problem. I need to mark somehow a statement in such a way that the comment is preserved through the binary log.&lt;br /&gt;I don't have control on how the statement is generated or using which client software. For the sake of example, let's say that I need to mark a &lt;code&gt;CREATE PROCEDURE&lt;/code&gt; statement in such a way that, if I extract the query from the binary log and apply it to another server, the information is still available. &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Background&lt;/h3&gt;Normally, I would use a comment. The first thing I would think is  &lt;br /&gt;&lt;code&gt;CREATE PROCEDURE p1(i int) select "hello" /* This is my text */&lt;/code&gt;&lt;br /&gt;But most client libraries will strip it. &lt;br /&gt;There was &lt;a href="http://rpbouman.blogspot.com/2006/12/mysql-stored-routines-and-command-line.html"&gt; a clever trick &lt;/a&gt; by &lt;a href="http://rpbouman.blogspot.com/"&gt;Roland Bouman&lt;/a&gt; that allowed users to bypass this limitation. You could use a qualified comment such as &lt;code&gt;/*!999999 This is my test */&lt;/code&gt;, but unfortunately it only works in MySQL 5.0.x, while MySQL 5.1 strips everything down, even if the comment is a legitimate keyword.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;create procedure p9 (j int) insert /*!50000 INTO */ t1 values (j) ;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt; show create procedure p9\G&lt;br /&gt;*************************** 1. row ***************************&lt;br /&gt;           Procedure: p9&lt;br /&gt;            sql_mode: &lt;br /&gt;    Create Procedure: CREATE DEFINER=`msandbox`@`%` PROCEDURE `p9`(j int)&lt;br /&gt;insert  INTO  t1 values (j)&lt;br /&gt;character_set_client: latin1&lt;br /&gt;collation_connection: latin1_swedish_ci&lt;br /&gt;  Database Collation: latin1_swedish_ci&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Other tricks&lt;/h3&gt;Something else that I have tried: I can inject a query before or after the one that I need to monitor.&lt;br /&gt;&lt;pre&gt;create table if not exists comments (t varchar(100)) engine=blackhole;&lt;br /&gt; &lt;br /&gt;update comments set t='the next statement is what I need';&lt;br /&gt;create procedure p1(i int) insert into t1 values (j);&lt;br /&gt;update comments set t='the previous statement is what I need';&lt;br /&gt;&lt;/pre&gt;This approach does possibly introduce some overhead.&lt;br /&gt;&lt;br /&gt;Or I can add a comment clause in the statement.&lt;br /&gt;&lt;pre&gt;create procedure p1(i int) comment="this is what I need" insert into t1 values (j);&lt;br /&gt;&lt;/pre&gt;This approach requires parsing the SQL, and dealing with artistic indentation and usage of other options in the query. And if I need to deal with commands that don't support the "comment" option, I am back to square one.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Advice wanted&lt;/h3&gt;So far, the only method that works almost always is the blackhole trick &lt;sup&gt;&lt;small&gt;(1)&lt;/small&gt;&lt;/sup&gt;&lt;br /&gt;I would like to know if there is any method of introducing a piece of information related to a given statement, in such a way that the comment survives after one of the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The binary log is converted to queries and passed to a MySQL client that applies the stream of queries to another server. &lt;/li&gt;&lt;li&gt;The binary log is associated with another master, and then passed to a slave through regular replication.&lt;/li&gt;&lt;/ul&gt;In both cases, I need to find the original information in the last server's binary log.&lt;br /&gt;&lt;br /&gt;As a related matter, I know that MySQL, in regular replication, passes some information across binary logs, and that information is the server-id. If I set an intermediate server as relay slave, the server-id of the original master is associated with the query recorder in the binary log of every slave. I don't know if I can use this information for my purposes, but I would like to know how does the replication process maintain the server ID across servers. &lt;br /&gt;&lt;br /&gt;Maybe it's too late for me and I can't see an obvious solution. I will appreciate any suggestion. Thanks in advance&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;small&gt;&lt;sup&gt;(1)&lt;/sup&gt; If the blackhole is disabled, the method fails, or introduce unacceptable overhead.&lt;/small&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-3896130790240444415?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/3896130790240444415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=3896130790240444415' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3896130790240444415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3896130790240444415'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/12/looking-for-hack-passing-comment-like.html' title='Looking for a hack - Passing comment-like info through the binary log'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_gVfZHGgf5LA/TQ_L1p1yldI/AAAAAAAAA_4/77FLiXP99Lg/s72-c/hack1_no_bg_300px.jpg' height='72' width='72'/><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1980497015011271957</id><published>2010-12-16T12:22:00.000+01:00</published><updated>2010-12-16T12:22:46.483+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stored procedures'/><category scheme='http://www.blogger.com/atom/ns#' term='GA'/><category scheme='http://www.blogger.com/atom/ns#' term='5.5'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='innodb'/><category scheme='http://www.blogger.com/atom/ns#' term='information_schema'/><title type='text'>Some hidden goods in MySQL 5.5</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://blogs.oracle.com/mysql/2010/12/mysql_55_is_ga.html"&gt;&lt;img alt="5.5 GA" border="0" src="http://lh3.ggpht.com/_gVfZHGgf5LA/TQnvFvMrsbI/AAAAAAAAA_k/s7zjhLVJ-BE/5_5_GA_logo.png" title="MySQL 5.5 GA" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;The announcement of &lt;a href="http://blogs.oracle.com/mysql/2010/12/mysql_55_is_ga.html"&gt;MySQL 5.5 released as GA&lt;/a&gt; has outlined the improvements in this version, which indeed has enough good new features to excite most any user.&lt;br /&gt;There are two additions, though, that were lost in the noise of the bigger features, and I would like to spend a few words for each of them.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The first addition is something that users of stored routines have been waiting for since MySQL 5.0. No, it is not SIGNAL and its close associate RESIGNAL, which have been publicized enough. I am talking about the &lt;b&gt;stored routine parameters&lt;/b&gt;, for which now there is a dedicated table in the information_schema.&lt;br /&gt;Let's see an example, with a simple procedure that uses three parameters.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;drop procedure if exists add_to_date ;&lt;br /&gt;create procedure add_to_date(in d date, in i int, out nd date)&lt;br /&gt;deterministic&lt;br /&gt;    set nd = d + interval i day;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This works as expected in both 5.1 and 5.5. (Never mind that it's redundant. I know it. It's only for the sake of keeping the example short).&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; call add_to_date('2010-12-15',10,@new_date);&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt; select @new_date;&lt;br /&gt;+------------+&lt;br /&gt;| @new_date  |&lt;br /&gt;+------------+&lt;br /&gt;| 2010-12-25 |&lt;br /&gt;+------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The difference starts to show when you want to deal with this procedure programmatically. If you need to find out which parameters are expected by this procedure, your only option in MySQL 5.1 is parsing the result of &lt;code&gt;SHOW CREATE PROCEDURE add_to_date&lt;/code&gt;. Not terribly difficult in any scripting language, but a hassle in SQL.&lt;br /&gt;In MySQL 5.5, instead, you can easily get the routine parameters with a simple query:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; select parameter_name, parameter_mode,data_type from information_schema. parameters where specific_schema='test' and specific_name= 'add_to_date' order by ordinal_position;&lt;br /&gt;+----------------+----------------+-----------+&lt;br /&gt;| parameter_name | parameter_mode | data_type |&lt;br /&gt;+----------------+----------------+-----------+&lt;br /&gt;| d              | IN             | date      |&lt;br /&gt;| i              | IN             | int       |&lt;br /&gt;| nd             | OUT            | date      |&lt;br /&gt;+----------------+----------------+-----------+&lt;br /&gt;3 rows in set (0.00 sec)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Speaking of the information_Schema, there are more goodies that were not emphasized enough. The Innodb engine that you find in the server is the evolution of the InnoDB plugin that ships with MySQL 5.1. Only that it is now built-in. What many people forget to mention is that the plugin (and thus the current InnoDB engine in 5.5) comes provided with its own &lt;b&gt;InnoDB-specific instrumentation tables in the information_schema&lt;/b&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;show tables like 'innodb%';&lt;br /&gt;+----------------------------------------+&lt;br /&gt;| Tables_in_information_schema (innodb%) |&lt;br /&gt;+----------------------------------------+&lt;br /&gt;| INNODB_CMP_RESET                       |&lt;br /&gt;| INNODB_TRX                             |&lt;br /&gt;| INNODB_CMPMEM_RESET                    |&lt;br /&gt;| INNODB_LOCK_WAITS                      |&lt;br /&gt;| INNODB_CMPMEM                          |&lt;br /&gt;| INNODB_CMP                             |&lt;br /&gt;| INNODB_LOCKS                           |&lt;br /&gt;+----------------------------------------+&lt;br /&gt;7 rows in set (0.00 sec)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This is the same set of tables that you may have seen if you have worked with the InnoDB plugin in 5.1. In short, you can get a lot of the info that you used to look at in the output of &lt;code&gt;SHOW ENGINE INNODB STATUS&lt;/code&gt;. For more information, you should look at what the &lt;a href="http://dev.mysql.com/doc/innodb/1.1/en/innodb-information-schema.html"&gt;InnoDB plugin manual&lt;/a&gt; says on this topic.&lt;br /&gt;I don't know if the tables can replace the SHOW ENGINE INNODB STATUS. Perhaps someone can comment on this issue and provide more information?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1980497015011271957?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1980497015011271957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1980497015011271957' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1980497015011271957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1980497015011271957'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/12/some-hidden-goods-in-mysql-55.html' title='Some hidden goods in MySQL 5.5'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_gVfZHGgf5LA/TQnvFvMrsbI/AAAAAAAAA_k/s7zjhLVJ-BE/s72-c/5_5_GA_logo.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-3892586577303623075</id><published>2010-12-09T11:30:00.000+01:00</published><updated>2010-12-09T11:30:30.952+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oreilly'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='speaking'/><title type='text'>Speaking at the O'Reilly MySQL Conference - April 2011</title><content type='html'>I will present two talks at the MySQL Conference next April.&lt;br /&gt;One is a three hours tutorial on &lt;b&gt;Advanced MySQL Replication Techniques&lt;/b&gt;, and the other is a normal session on &lt;b&gt;The art of sandboxing. Reducing Complex Systems to Manageable Boxes&lt;/b&gt;.&lt;br /&gt;The first topic is not a first to me. But the contents are going to be fresh and new. There has been so much going on in the replication field, that the talk on this topic that I presented in 2007 looks like ancient history.&lt;br /&gt;The second topic is completely new. I have often presented the result of my sandboxing efforts, but I have never thought of explaining the techniques themselves. Now that I have got some experience at reducing differently complex systems to sandboxes, I want to share the knowledge, to promote more work in this field.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-3892586577303623075?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/3892586577303623075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=3892586577303623075' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3892586577303623075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/3892586577303623075'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/12/speaking-at-oreilly-mysql-conference.html' title='Speaking at the O&apos;Reilly MySQL Conference - April 2011'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-2674207788389362317</id><published>2010-12-06T06:30:00.002+01:00</published><updated>2010-12-06T09:46:08.897+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='backup'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><category scheme='http://www.blogger.com/atom/ns#' term='mysqldump'/><title type='text'>Excluding databases from mysqldump</title><content type='html'>A question that came up during the MySQL track at the UKOUG conference in Birmingham was "Can I exclude only a few databases from mysqldump? Let's say that I have 50 databases, and I want to dump all of them, except a few."&lt;br /&gt;As many know, mysqldump has an option to ignore specific tables. SO if you have 1,000 tables in a databases, you can tell mysqldump to dump all the tables except a few ones.&lt;br /&gt;There is no corresponding option to exclude one or more databases.&lt;br /&gt;However, if you know your command line tools, the solution is easy:&lt;br /&gt;First, we get the list of all databases:&lt;br /&gt;&lt;pre&gt;mysql -B -N -e 'show databases'&lt;br /&gt;information_schema&lt;br /&gt;employees&lt;br /&gt;five&lt;br /&gt;four&lt;br /&gt;mysql&lt;br /&gt;one&lt;br /&gt;performance_schema&lt;br /&gt;six&lt;br /&gt;test&lt;br /&gt;three&lt;br /&gt;two&lt;br /&gt;&lt;/pre&gt;-B forces batch mode (no dashes box around the data), while -N gets the result without the headers.&lt;br /&gt;Now, let's say that we want to exclude databases four, five, and six. And since we want to avoid unpleasant side effects, also information_schema and performance_schema.&lt;br /&gt;Thus, we pipe the previous data through a filter. I use Perl, but sed or grep could get the job done.&lt;br /&gt;&lt;pre&gt;mysql -B -N -e 'show databases' | \&lt;br /&gt;  perl -ne 'print unless /\b(?:four|five|six|_schema)\b/' &lt;br /&gt;employees&lt;br /&gt;mysql&lt;br /&gt;one&lt;br /&gt;test&lt;br /&gt;three&lt;br /&gt;two&lt;br /&gt;&lt;/pre&gt;Now that we have the list of databases that we need, we can tell mysqldump to backup the databases from such list. All we need is converting the vertical list into a horizontal one using xargs&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;mysql -B -N -e 'show databases' | \&lt;br /&gt;  perl -ne 'print unless /\b(?:four|five|six|_schema)\b/' \&lt;br /&gt;  xargs echo mysqldump -B &lt;br /&gt;&lt;b&gt;mysqldump -B employees mysql one test three two&lt;/b&gt;&lt;br /&gt;&lt;/pre&gt;That's it. The last line is the resulting command. Once you are sure that it is what you want, remove the "echo" after xargs, and the command will be executed.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; Thanks to Shantanu, who pointed that the regexp does not filter properly. So I added the boundary checks (\b) to make my words match the result.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-2674207788389362317?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/2674207788389362317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=2674207788389362317' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2674207788389362317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/2674207788389362317'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/12/excluding-databases-from-mysqldump.html' title='Excluding databases from mysqldump'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-577345856062581100</id><published>2010-12-03T19:26:00.000+01:00</published><updated>2010-12-03T19:26:55.569+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='stuttgart'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>My picks for PGDay-EU 2010</title><content type='html'>&lt;a href="http://2010.pgday.eu/"&gt;&lt;img alt="PGDayEU2010" border="0" src="http://lh4.ggpht.com/_gVfZHGgf5LA/TPkvyXYdfII/AAAAAAAAA_U/Gsev_npcAkw/Screen%20shot%202010-12-03%20at%2018.57.06%20.png" title="PGDay EU 2010" /&gt;&lt;/a&gt; &lt;br /&gt;On Sunday I will be in Stuttgart with the double purpose of attending the &lt;a href="http://2010.pgday.eu/"&gt;annual European PostrgreSQL conference&lt;/a&gt; and the technical meeting of &lt;a href="http://continuent.com/"&gt;my company&lt;/a&gt; that will be held after the normal proceedings of PGDay-EU.&lt;br /&gt;For the first time in several years I am attending a conference where I am not a speaker. In my previous job I did not have much opportunity to attend PostgreSQL meetings, and I welcome this opportunity. The &lt;a href="http://www.postgresql.eu/events/schedule/pgday2010/"&gt;schedule&lt;/a&gt; is quite interesting, and I have made my personal picks:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Monday:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.postgresql.eu/events/schedule/pgday2010/session/41-keynote-back-to-the-future-of-open-source/"&gt;09:45 - 10:45 Keynote: Back To The Future of Open Source&lt;/a&gt;.&lt;br /&gt;Simon Phipps has always an interesting way of making a topic interesting. Looking forward to hearing what he has to say.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.postgresql.eu/events/schedule/pgday2010/session/54-play-chess-against-postgresql-and-get-beaten/"&gt;11:10 - 12:00 Play chess against PostgreSQL (and get beaten)&lt;/a&gt;.&lt;br /&gt;For a chess enthusiast and database professional, this talk is going to be doubly interesting!&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.postgresql.eu/events/schedule/pgday2010/session/55-managing-postgresql-replication/"&gt;12:10 - 13:00 Managing PostgreSQL Replication&lt;/a&gt;. &lt;br /&gt;In my new job, this topic is going to be paramount.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.postgresql.eu/events/schedule/pgday2010/session/63-liberating-your-data-from-mysql-cross-database-replication-to-the-rescue/"&gt;14:00 - 14:50 Liberating Your Data From MySQL: Cross-Database Replication to the Rescue!&lt;/a&gt;. &lt;br /&gt;This will be a presentation of Tungsten cross DBMS replication, therefore interesting for many personal reasons!&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.postgresql.eu/events/schedule/pgday2010/session/67-concurrency-postgresql/"&gt;15:20 - 16:10 Concurrency &amp;amp; PostgreSQL&lt;/a&gt;.&lt;br /&gt;Undoubtedly a topic that will become quite useful when dealing with PG replication issues that I will be facing in my job. &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Tuesday:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.postgresql.eu/events/schedule/pgday2010/session/91-postgresql-extensions-development/"&gt;14:10 - 15:00 PostgreSQL extension's development&lt;/a&gt;.&lt;br /&gt;I know a lot about extensions in MySQl. It's time to start learning similar about PG!&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.postgresql.eu/events/schedule/pgday2010/session/51-closing-keynote-postgresqls-time-to-shine-the-most-disruptive-force-in-open-source-since-linux/"&gt;15:30 - 16:20 Closing keynote: PostgreSQL's Time to Shine: The most disruptive force in open source since Linux&lt;/a&gt;&lt;br /&gt;This sounds like a juicy strategic talk.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-577345856062581100?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/577345856062581100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=577345856062581100' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/577345856062581100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/577345856062581100'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/12/my-picks-for-pgday-eu-2010.html' title='My picks for PGDay-EU 2010'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_gVfZHGgf5LA/TPkvyXYdfII/AAAAAAAAA_U/Gsev_npcAkw/s72-c/Screen%20shot%202010-12-03%20at%2018.57.06%20.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5368199688548121870</id><published>2010-12-03T10:32:00.001+01:00</published><updated>2010-12-03T15:05:10.764+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='percona'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='gpl'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='participation'/><category scheme='http://www.blogger.com/atom/ns#' term='mariadb'/><category scheme='http://www.blogger.com/atom/ns#' term='forks'/><title type='text'>Who's afraid of MySQL forks?</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://dev.mysql.com/"&gt;&lt;img alt="mysql forks?" border="0" src="http://lh4.ggpht.com/_gVfZHGgf5LA/TPQotfb2heI/AAAAAAAAA_Q/1oPbudynGfQ/mysql_forks.png" title="MySQL forks?" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;There is much talk about MySQL forks and how they are going to replace MySQL, or take over MySQL user base, or become more powerful/profitable/popular/you-name-it than MySQL itself.&lt;br /&gt;Let's clear some air on this topic. There is more about forks than meets the eye, especially if you think about a few obvious facts.&lt;br /&gt;What's a fork? According to &lt;a href="http://en.wikipedia.org/wiki/Fork_%28software_development%29"&gt;Wikipedia&lt;/a&gt; &lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;a project fork happens when developers take a legal copy of source code from one software package and start independent development on it, creating a distinct piece of software.&lt;/i&gt;&lt;/blockquote&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;By this definition, when someone who doesn't work at the MySQL project distributes a package that is based on MySQL code but differs from the original, it's a fork.  &lt;br /&gt;Why am I approaching the issue from this angle? Because, apart from Windows users, who mostly download MySQL from the official site, the majority of users get MySQL through a Linux distribution or some other project. And most of the time such packages are different from the ones built by the MySQL team. There is nothing wrong with that. The differences are sometimes minimal packaging changes done to adapt MySQL to the specific distribution, and sometimes they are a cherry-picking application of patches to an old version that needs to be maintained so that the package is unlike any other MySQL version that you may find in the wild. Even if the version is the same, depending on the distribution and the age of the server, the code beneath could be wildly different from the official versions.&lt;br /&gt;Thus, it turns out that many users, possibly the majority, are using a MySQL fork, albeit a very minor one.&lt;br /&gt;But when people talk about forks, they often refer to three main projects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The &lt;a href="http://www.percona.com/"&gt;Percona&lt;/a&gt; distribution. This is a collection of a few distinct patches in the server, coupled with a fork of the InnoDB plugin, named XtraDB, and an independent tool for backup (XtraBackup). This fork has a solid business background. Every patch has been developed to meet user requests, and the engineers at Percona maintain them appropriately.&lt;/li&gt;&lt;li&gt;Then we have the &lt;a href="http://mariadb.org/"&gt;MariaDB&lt;/a&gt; fork, which is a series of changes to the MySQL core, motivated by the desire of the developers to build a rich set of feature enhancements while being backward compatible to the main distribution. The business model is thus a fast track of new features and bug fixes to customers.&lt;/li&gt;&lt;li&gt;And then there is &lt;a href="http://drizzle.org/"&gt;Drizzle&lt;/a&gt;, which has even less business traction than MariaDB, but a very well defined goal of creating a lightweight database by re-engineering a bare bones stripped down version of MySQL that is now very distant from its origins. &lt;/li&gt;&lt;/ul&gt;What I said in the above descriptions is just the synopsis of what these three forks are. In recent mythology, it is fabled that, if MySQL ceases to exist (because it goes bankrupt, or Oracle kills it, or a major accident happens to the project, whatever) users can replace MySQL with one fork, and live happily ever after.&lt;br /&gt;Not so fast. There is something that few people take into account when listening to this too often repeated tale. &lt;br /&gt;What most observers miss is that the forks' original code (with the exception of Drizzle) is very marginal. The bulk of the distribution is still the code produced by the MySQL team, which is merged at every minor release, and integrated with the patches produced by Percona and MariaDB. So, while technically they are forks of MySQL, they can't live independently from the official MySQL distribution. Both Percona and MariaDB don't have the manpower to maintain the server by handling the huge amount of bugs that the MySQL team is fixing every month.&lt;br /&gt;There is also a matter of skill set. Percona has talented InnoDB experts, while MariaDB has mostly core server experts (and some are among the top ones, I may add). They could complement each other, although it seems that cooperation between the two projects is not as good as it used to be. (Could be my personal impression.)&lt;br /&gt;The bottom line, though, is if both projects are able to survive should the main project become unavailable. I am not suggesting that Oracle wants to make MySQL scarce. On the contrary, all the information at my disposal suggest that Oracle will keep MySQL publicly available for long time. &lt;br /&gt;This state of affair seems to indicate that Drizzle is, instead, a true fork that does not depend on MySQL health. To some extent, this is true. However, the main storage engine in Drizzle is InnoDB. Therefore, at least today, Drizzle is as dependent on Oracle as Percona and MariaDB. &lt;br /&gt;What would happen tomorrow, if the disaster depicted by doomsday advocates comes true and MySQL actually disappears? I don't honestly know, but I would love to have a public commitment from the major players, about what they are prepared to do in terms of maintaining that huge chunk of code that today they take from Oracle releases on a monthly basis. &lt;br /&gt;This is all matter of thought for MySQL users. &lt;br /&gt;&lt;br /&gt;About adoption of the forks today, I have seen five types of arguments in favor of  a MySQL fork:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;&lt;ol&gt;&lt;li&gt;I need the feature provided by Percona or MariaDB, or I need a quick bug fix that I can't get from the slow roadmap at Oracle. I trust that this handful of people are able to maintain that little code that differs from MySQL and matters to me. So I don't care if they don't have 100 developers on the task.&lt;/li&gt;&lt;li&gt;Given Oracle's track record in other Open Source projects, I don't trust them to deliver MySQL according to FOSS principles, so let's go for true Open Source alternatives.&lt;/li&gt;&lt;li&gt;Most MySQL developers have now left Oracle, and so the forks have more chances of being higher quality.&lt;/li&gt;&lt;li&gt;Cool! MariaDB/Percona has a bunch of features more than MySQL. It must be better. Let's use it.&lt;/li&gt;&lt;li&gt;I like new technology. Let's plunge into them!&lt;/li&gt;&lt;/ol&gt;&lt;/i&gt;&lt;/blockquote&gt;Argument #1 is a solid business backed reason for adopting some software. The risk is often well calculated, especially if the evaluation can be backed by performance and functional tests.&lt;br /&gt;Argument #2 is frivolous, as it mixes subjective feelings into business matters. And so is argument #4. Yet, these two types of advocacy are quite popular and spread much faster than the more reasonable approach seen at #1.&lt;br /&gt;Argument #3 is debatable. MySQL developers at Oracle outnumber all forks easily. The idea that the departure of a few core developers can alter the system in such a way that the whole project crumble has been already negated by facts: MySQL 5.5 is an excellent release, with enthusiastic appreciation from power users.  While I agree that top MySQL talents work at the forks, I consider the MySQL team to be still in excellent shape.&lt;br /&gt;Argument #5 is reasonable, &lt;b&gt;if&lt;/b&gt; it is followed by cool judgment and backed by facts. I am one who is always ready to try new solutions, and love experimenting with cool technology. But adoption is different from proof of concept. I am happy to see that Drizzle can replace MySQL in some applications, but would I trust it in its present beta stage? Certainly not. So, I am happy to test, but I trust my valuable data to more stable solutions.&lt;br /&gt;&lt;br /&gt;What's for you, the final user? My personal advice is: don't adopt blindly because of some enthusiastic advertising. But test the product thoroughly, and if it fits your needs, by all means, go for it. But if you don't have a specific reason, I recommend staying with the official branch, because, despite the change in affiliation, there is still a well experienced team behind it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5368199688548121870?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5368199688548121870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5368199688548121870' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5368199688548121870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5368199688548121870'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/12/whos-afraid-of-mysql-forks.html' title='Who&apos;s afraid of MySQL forks?'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_gVfZHGgf5LA/TPQotfb2heI/AAAAAAAAA_Q/1oPbudynGfQ/s72-c/mysql_forks.png' height='72' width='72'/><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5616781279714941807</id><published>2010-11-28T15:24:00.000+01:00</published><updated>2010-11-28T15:24:16.054+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='transactions'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='licensing'/><category scheme='http://www.blogger.com/atom/ns#' term='acid'/><category scheme='http://www.blogger.com/atom/ns#' term='innodb'/><category scheme='http://www.blogger.com/atom/ns#' term='fud'/><category scheme='http://www.blogger.com/atom/ns#' term='autocommit'/><category scheme='http://www.blogger.com/atom/ns#' term='myth'/><title type='text'>Dispelling some unintentional MySQL FUD</title><content type='html'>&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt; &lt;a href="http://dev.mysql.com"&gt;&lt;img src="http://lh6.ggpht.com/_gVfZHGgf5LA/TPJWVJwXx9I/AAAAAAAAA_M/JD2BwIvzAf0/Sakila_chopping_FUD_2.png" width="400" alt="Sakila dispelling FUD" title="Knowledge is power - FUD is darkness" border="0"&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt; There are three types of FUD: the first and more genuine is (#1) the intentional &lt;a href="http://en.wikipedia.org/wiki/Fear,_uncertainty_and_doubt"&gt;spreading of falsehood&lt;/a&gt;, mostly to gain some marketing advantage over a competing product. While I despise this practice, I understand it. &lt;br /&gt;Then there is (#2) FUD spread by ignorance, when the originators are so blindly enraged by their hatred  for a product that they don't care about getting the facts straight. &lt;br /&gt;And finally, there is a third kind, not less dangerous, which is (#3) the spreading of FUD with good intentions, when the authors believe that they have the facts straight and they want to help.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;I have recently come across two examples of unintentional FUD. For different reasons, my comments to these public cases did not get through, and then I have to say something about that here in my blog.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;MySQL is not ACID complaint&lt;/h3&gt;&lt;a href="http://www.remotedbaexperts.com/Blog/2010/11/mysql-is-not-acid-compliant/"&gt;This surprising piece of news&lt;/a&gt; came in the blog of a company that calls itself &lt;i&gt;the remote DBA experts&lt;/i&gt;. &lt;br /&gt;The claim is this: if I insert a record in a table and then issue a ROLLBACK command, the record is not rolled back.&lt;br /&gt;Anyone who has a minimal knowledge of MySQL knows about InnoDB tables (luckily for the poster, InnoDB is default in MySQL 5.5.6, which he was testing) and autocommit.&lt;br /&gt;Reading through the example, one sees that the poster did not know about this piece of information. In MySQL, &lt;code&gt;autocommit&lt;/code&gt; is ON by default. So if you want to rollback a record, you need to deactivate it. This is not optimal, and it can be debated, but if you read the docs, you don't claim something that is simply the result of your lack of knowledge. MySQL has shortcomings, but being unable to rollback a record is not one of them. Hence, this is FUD type #2.&lt;br /&gt;Why I am writing all this here and not as a comment in that blog? Because I did post a comment, on November 23rd, but as of today, it has not been approved yet. The same is true for comments posted by other more knowledgeable people.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;MySQL licenses. When it's free and when you need to pay for one.&lt;/h3&gt;This article is well intentioned. &lt;a href="http://blog.schonewille.tk/mysql-licenses-the-dos-and-donts-of-open-sour"&gt;MySQL Licenses: The Do's and Don'ts of Open Source, or What's All the Fuss About?&lt;/a&gt; is a well thought piece, with practical examples, to help users decide what to do with MySQL licensing, i.e. when they need to pay and when they don't. Unfortunately, the article contains some unintentional confusion, and therefore leaves the readers with more wrong ideas than they had before.&lt;br /&gt;I left a long comment on that blog, but for some unfathomable reason it was reduced to a tiny piece, and thus the need for explaining the matter here again.&lt;br /&gt;The poster says this:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;I make commercial software, which needs to have MySQL installed. My customers can use my commercial software, for which they do need to buy a license, in combination with the MySQL database engine, for which they don't need to pay. Because the MySQL engine is not embedded in my commercial software and I don't redistribute MySQL together with my software, I don't need a commercial license for MySQL and neither do my customers.&lt;br /&gt;&lt;/i&gt;&lt;/blockquote&gt;I am afraid that this wishful information is not correct. The &lt;a href="http://www.gnu.org/licenses/gpl-faq.html#IfLibraryIsGPL"&gt;GPL FAQ&lt;/a&gt; states it clearly:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;If a library is released under the GPL (not the LGPL), does that mean that any program which uses it has to be under the GPL or a GPL-compatible license?&lt;br /&gt;Yes, because the program as it is actually run includes the library.&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;Another quote:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;However... as long as I have no desire to sell the embedded MySQL source code commercially, I can let the GPL license apply. &lt;/i&gt;&lt;/blockquote&gt;Also this is not true. The GPL does not regulate commercial transactions. It only deals with distribution of software. If I want to distribute a public domain but GPL-incompatible software linked to a GPL application or library, I am violating the GPL, even if I don't charge anything.&lt;br /&gt;&lt;br /&gt;Another source of disinformation is &lt;i&gt;"If you decide to pay for a MySQL license, you don't actually pay for the software."&lt;/i&gt;&lt;br /&gt;This is also incorrect. Oracle sells two kind of things with MySQL. One thing is a subscription to services (MySQL Enterprise). If you buy this, you are not getting a license (unless you ask for it explicitly) but an agreement about services for a given periods.&lt;br /&gt;The other thing that Oracle sells is licenses. They can do it because they own the source code, and they can decide to release it either as GPL (which is what you download from &lt;a href="http://dev.mysql.com/downloads"&gt;the MySQL site&lt;/a&gt;) or with a commercial license. If you ask for a license, you will most definitely get one. You can also get a license together with a subscription, if you are so inclined, but that doesn't mean that you aren't buying a license.&lt;br /&gt;The important thing to understand to put the matter in perspective, is that the above information about licensing was still true before 2008, when MySQL was owned by &lt;i&gt;MySQL AB&lt;/i&gt;, and it is still true today. Oracle, despite all the preemptive accusations of being ill intentioned, has not changed the rules of the game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5616781279714941807?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5616781279714941807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5616781279714941807' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5616781279714941807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5616781279714941807'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/dispelling-some-unintentional-mysql-fud.html' title='Dispelling some unintentional MySQL FUD'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_gVfZHGgf5LA/TPJWVJwXx9I/AAAAAAAAA_M/JD2BwIvzAf0/s72-c/Sakila_chopping_FUD_2.png' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5509863655581054265</id><published>2010-11-28T13:15:00.000+01:00</published><updated>2010-11-28T13:15:45.379+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oreilly'/><category scheme='http://www.blogger.com/atom/ns#' term='aldiko'/><category scheme='http://www.blogger.com/atom/ns#' term='amazon'/><category scheme='http://www.blogger.com/atom/ns#' term='ebook'/><category scheme='http://www.blogger.com/atom/ns#' term='reading'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>A world of ebooks</title><content type='html'>&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt; &lt;a href="http://amzn.com/w/30Z9CI8F8GSUL"&gt;&lt;img src="http://lh3.ggpht.com/_gVfZHGgf5LA/TPIt-vb6CzI/AAAAAAAAA_I/16Y3E7RyiWM/ebooks.png" alt="ebooks" title="ebooks" border="0"&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt; I am a &lt;a href="http://en.wikipedia.org/wiki/Bibliophile"&gt;bibliophile&lt;/a&gt;, or, to say it in plain English, a book lover. I have been collecting books since I was in first grade. I read books at high speed, which is both a blessing and a curse. A blessing, because I can squeeze useful information out of a book very quickly, and that's useful for my job, and for some of my hobbies. A curse, because when I travel one book is usually not enough to keep me busy for the whole travel, and I need to carry or buy more, with negative effects on the weight of my luggage and my on my back. Ten years ago I had a brief but intense experience with electronic books in a Palm hand held device. It didn't last long, though. The quality of ebooks and readers in that period was less than optimal, and I have left the matter rest for a while.&lt;br /&gt;In the meantime, I kept collecting electronic books, mostly PDF editions of technical books that I keep in my laptop for quick reference. Reading them from cover to cover, though, is not a pleasant experience in a laptop. Ditto for reading fiction or essays. The laptop screen is not comfortable for such exercise.&lt;br /&gt;Then, last year, I bough an &lt;a href="http://www.onyx-international.com/en/A_pr2.php"&gt;ebook reader&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; That changed the whole business. Reading ebooks became very similar to reading paper books. The size of the screen and the ability of increasing font size makes your reading a pleasure. As for my back and luggage problems, that's solved hands down. The weight of the device is the same, no matter if I carry one ebook or one hundred.&lt;br /&gt;Suddenly, the dozen of ebooks that I had kept idle in my laptop sprang to life, and I was able to read them like a paper book, easily, comfortably, and with pleasure.&lt;br /&gt;I started buying more ebooks, both of fiction and of technical matters. The latter are especially welcome. Whenever I travel to conferences, I am tempted to buy some useful book, and then I regret when it burdens my backpack during the trip home, and fights for room on my overcrowded book shelves. No more of this. Now, when I visit a book booth at a conference, I simply take note of the interesting titles, and then I buy the ebooks at the publisher's site directly. If there is no ebook, I can easily convince me that the book is not really needed.&lt;br /&gt;A few months ago there was some new development. My ebook reader's screen was faulty. It was showing a few unwanted lines at the bottom and the top of the screen, making it difficult to read menus. No big deal. I sent it to the manufacturer, which replaced the screen for free. The only trouble was that the replacement took three months! During that period, I experienced reading ebooks (to which I was by then addicted) with my Android phone, using a wonderful application named &lt;a href="http://www.aldiko.com/"&gt;Aldiko&lt;/a&gt;. The user friendliness of this app more than compensated for the smaller screen size, and I was able to read technical and fiction books with little problem. But I was missing the big screen. So the delay of the back shipment was partially responsible for the lowering of my defenses, when I entered an Apple store and I couldn't leave without a new iPad.&lt;br /&gt;I felt guilty for a while, but the guilt disappeared in a matter of hours, when I loaded all my ebooks in the iPad, and saw what a difference a bigger and colorful screen does. Compared to the six inches of my ebook reader, the iPad is huge, and the reading is even easier and more pleasurable. I was hooked.&lt;br /&gt;Since then, my personal library of ebooks has grown rapidly. I have bought 90 (yes, ninety) books from &lt;a href="http://oreilly.com/"&gt;O'Reilly&lt;/a&gt;, including many that I had already bought on paper, and now I am giving away to friends and libraries. &lt;br /&gt;I need to spend a few words of praise for O'Reilly. In the jungle of book publishing, O'Reilly is the best and more user friendly publisher available. The quality of its books is excellent, the choice of catalog vast and modern, the service impeccable. There are other publishers that offer comparable quality (e.g. &lt;a href="http://pragprog.com/"&gt;the Pragmatic bookshelf&lt;/a&gt; or &lt;a href="http://www.manning.com/"&gt;Manning&lt;/a&gt;) but not the same rich catalog, or a similarly vast catalog (e.g. &lt;a href="https://www.packtpub.com/"&gt;Packt Publishing&lt;/a&gt;) but not the same quality. &lt;br /&gt;If I have to note any negative points about O'Reilly, is that there is no wish list in their shop. So, for now, I am restricting my wishes to &lt;a href="http://amzn.com/w/30Z9CI8F8GSUL"&gt;my list on Amazon&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5509863655581054265?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5509863655581054265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5509863655581054265' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5509863655581054265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5509863655581054265'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/world-of-ebooks.html' title='A world of ebooks'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_gVfZHGgf5LA/TPIt-vb6CzI/AAAAAAAAA_I/16Y3E7RyiWM/s72-c/ebooks.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-977563335068143061</id><published>2010-11-21T17:32:00.001+01:00</published><updated>2010-11-25T15:58:03.292+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='workbench'/><title type='text'>How MySQL Workbench breaks itself</title><content type='html'>Once upon a time, there was a policy in MySQL not to add new features after the beta stage.&lt;br /&gt;To my surprise, &lt;a href="http://wb.mysql.com/?p=833"&gt;MySQL Workbench 5.2.30&lt;/a&gt; introduces a new feature, the query formatter. I gave it a try. The results are not extremely encouraging. Granted, it's a plugin and not a feature in the core application, but nonetheless one would expect something more stable in a GA release, especially since the plugin features are displayed in the main menu, and unless you have read the &lt;a href="http://wb.mysql.com/?p=833"&gt;announcement&lt;/a&gt;, you couldn't easily tell the core from the plugins.&lt;br /&gt;This is what I have got in just a few minutes:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bugs.mysql.com/58356"&gt; Bug #58356: beautify function fails on CREATE TABLE &lt;/a&gt;&lt;br /&gt;&lt;a href="http://bugs.mysql.com/58357"&gt; Bug #58357: beutify function erases statement on CREATE INDEX &lt;/a&gt; &lt;br /&gt;&lt;a href="http://bugs.mysql.com/58358"&gt; Bug #58358: query formatter fails on selected query  &lt;/a&gt;&lt;br /&gt;&lt;a href="http://bugs.mysql.com/58359"&gt; Bug #58359: query formatter indentation fails on partially selected query &lt;/a&gt;&lt;br /&gt;&lt;a href="http://bugs.mysql.com/58360"&gt; Bug #58360 query formatter converts non-keywords to uppercase &lt;/a&gt;&lt;br /&gt;&lt;a href="http://bugs.mysql.com/58360"&gt;Bug #58361 Query formatter mangles query when CASE operator is used&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;MySQL Workbench is a great product. I would like it to be more solid. New features, even as a plugin, should be more carefully released that this one.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;. 4 days after my submission, the WB team has fixed all 6 of them. Kudos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-977563335068143061?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/977563335068143061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=977563335068143061' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/977563335068143061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/977563335068143061'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/how-mysql-workbench-breaks-itself.html' title='How MySQL Workbench breaks itself'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-6180621817315153146</id><published>2010-11-19T15:19:00.001+01:00</published><updated>2010-11-19T16:34:20.822+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qa'/><category scheme='http://www.blogger.com/atom/ns#' term='laptop'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><title type='text'>How to create a private cloud in your laptop</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188933703/" title="private cloud laptop by datacharmer, on Flickr"&gt;&lt;img alt="private cloud laptop" border="0" height="240" src="http://farm2.static.flickr.com/1286/5188933703_9c286ff58e_m.jpg" width="218" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Everybody is moving to cloud architectures, although not all agree on what cloud computing is. In my limited understanding, and for the purpose of my work, cloud computing is a quick and versatile availability of virtual machines. &lt;br /&gt;Now, if my purpose was deploying these machines, a private cloud in one host (namely, my laptop) would not make sense. But to create a flexible testing environment, it works very well. &lt;br /&gt;Users of virtual machines software such as VMWare or VirtualBox may ask what's new here. You can create many virtual machines and use them within the same host.&lt;br /&gt;True, but creating a new virtual machine in one minute without duplication of resources is not so easy. This is what this article covers. More specifically, it covers how to clone virtual machines efficiently with VMWare Fusion on a Mac OSX laptop.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;I have been a VMWare user for more than 10 years, mostly on Linux, where I used VMWare Workstation. One of the features that I liked on that application was the ability of cloning virtual machines, where the clones share the disk with the original VM. VMWare Fusion does not have a cloning feature, but there are ways of achieving the same result.&lt;br /&gt;If you copy a virtual machine and then open it with Fusion, it will ask you if you have copied it, and after your answer, it will use the new virtual machine independently from the first one. The only problem is that you will have twice as much disk space occupied. So, in addition to the space that will eventually got eaten up in your limited laptop, the duplication process is slow (copying 10 GB does not happen instantly). The method shown here will instead allow you to clone a virtual machine in less than one minute.&lt;br /&gt;&lt;h2&gt;Part I - How to clone a virtual machine&lt;/h2&gt;I have got this recipe from &lt;a href="http://communities.vmware.com/docs/DOC-5611"&gt;HOWTO: Manual Linked Cloning in Fusion&lt;/a&gt;, a year old tutorial that I have integrated with updated images.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Do it once - Create a virtual machine with everything you need. &lt;/h3&gt;This is a once only step. Install a virtual machine as usual. In my case, I used Ubuntu server 10.10. When I said &lt;i&gt;with everything you need&lt;/i&gt; I mean making sure that everything you think it will be necessary should be installed in this base VM. If you don't, you may end up installing the same thing in every cloned virtual machine.&lt;br /&gt;What I did was updating the software, then installing the &lt;code&gt;build-essential&lt;/code&gt; package and the VMWare tools, and then enabling the "partner" repository to install the original Sun Java packages instead of the default OpenJDK. Next, I downloaded the source code for MySQL 5.5 and made sure that I had all the software necessary to compile and build the database.&lt;br /&gt;Finally, I updated the CPAN with my favorite modules, stopped the virtual machine,  and I was ready for the next step.&lt;br /&gt;What I had in my hands was a working virtual machine. In order to make it clonable, I will go through some basic steps.&lt;br /&gt;&lt;h4&gt;Step 1. Copy the VM disks&lt;/h4&gt;I create a new directory under the same path where the normal virtual machines are. I called it &lt;b&gt;ub_srv_10_base&lt;/b&gt;, and I copied the .vmdk files into this new directory.&lt;br /&gt;&lt;h4&gt;Step 2. Modify the base disk to refer to fixed paths&lt;/h4&gt;In each virtual machine, the disk that has the same name as the VM (without numerals) is a sort of index of the real files containing the data. This file needs to be edited for further usage. Originally, it looked like this:&lt;br /&gt;&lt;pre&gt;# Disk DescriptorFile&lt;br /&gt;version=1&lt;br /&gt;encoding="UTF-8"&lt;br /&gt;CID=f88ac433&lt;br /&gt;parentCID=ffffffff&lt;br /&gt;isNativeSnapshot="no"&lt;br /&gt;createType="twoGbMaxExtentSparse"&lt;br /&gt;&lt;br /&gt;# Extent description&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s001.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s002.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s003.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s004.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s005.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s006.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s007.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s008.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s009.vmdk"&lt;br /&gt;RW 4192256 SPARSE "ubuntu_server_10-s010.vmdk"&lt;br /&gt;RW 20480 SPARSE   "ubuntu_server_10-s011.vmdk"&lt;br /&gt;&lt;br /&gt;# The Disk Data Base &lt;br /&gt;#DDB&lt;br /&gt;&lt;br /&gt;ddb.toolsVersion = "8323"&lt;br /&gt;ddb.virtualHWVersion = "7"&lt;br /&gt;ddb.longContentID = "d14a2f23de35287969b8eaebf88ac433"&lt;br /&gt;ddb.uuid = "60 00 C2 98 72 3b 6e 76-ff 05 b7 ff 8a 07 6e 92"&lt;br /&gt;ddb.geometry.cylinders = "2610"&lt;br /&gt;ddb.geometry.heads = "255"&lt;br /&gt;ddb.geometry.sectors = "63"&lt;br /&gt;ddb.adapterType = "lsilogic"&lt;br /&gt;&lt;/pre&gt;To make it usable, I added a relative path to the file names, and removed the UUID.&lt;br /&gt;&lt;pre&gt;# Disk DescriptorFile&lt;br /&gt;version=1&lt;br /&gt;encoding="UTF-8"&lt;br /&gt;CID=f88ac433&lt;br /&gt;parentCID=ffffffff&lt;br /&gt;isNativeSnapshot="no"&lt;br /&gt;createType="twoGbMaxExtentSparse"&lt;br /&gt;&lt;br /&gt;# Extent description&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s001.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s002.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s003.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s004.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s005.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s006.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s007.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s008.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s009.vmdk"&lt;br /&gt;RW 4192256 SPARSE "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s010.vmdk"&lt;br /&gt;RW 20480 SPARSE   "&lt;b&gt;../ub_srv_10_base/&lt;/b&gt;ubuntu_server_10-s011.vmdk"&lt;br /&gt;&lt;br /&gt;# The Disk Data Base &lt;br /&gt;#DDB&lt;br /&gt;&lt;br /&gt;ddb.toolsVersion = "8323"&lt;br /&gt;ddb.virtualHWVersion = "7"&lt;br /&gt;ddb.longContentID = "d14a2f23de35287969b8eaebf88ac433"&lt;br /&gt;&lt;b&gt;# ddb.uuid = "60 00 C2 98 72 3b 6e 76-ff 05 b7 ff 8a 07 6e 92"&lt;/b&gt;&lt;br /&gt;ddb.geometry.cylinders = "2610"&lt;br /&gt;ddb.geometry.heads = "255"&lt;br /&gt;ddb.geometry.sectors = "63"&lt;br /&gt;ddb.adapterType = "lsilogic"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now the file is ready to be used by other virtual machines. Notice that the files in this directory do not make a virtual machine. Only the storage part is here.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Step 3. Make the disks read-only&lt;/h4&gt;We need to make sure that the base disks are not modified. So, we remove the "w" attribute from all the files in the base directory.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$ chmod a-w ub_srv_base/*s0*&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Step 4. Remove the original virtual machine&lt;/h4&gt;Make a copy if you want. And actually having a backup of the base disk directory is a very good idea. Compress it and save it to a good location. But remove the virtual machine from Fusion. This will avoid confusion later on.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Do it many times - Create a clone&lt;/h3&gt;This process looks frightfully long, especially if you count the images below, but in reality it's very quick and painless. Once you get familiar with it, you will be cloning virtual machines in no time at all.&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5189522424/" title="vm1 by datacharmer, on Flickr"&gt;&lt;img alt="vm1" border="1" height="361" src="http://farm5.static.flickr.com/4112/5189522424_edba9a4610.jpg" width="500" /&gt;&lt;/a&gt;&lt;br /&gt;Back in VMWare Fusion, select "create a new Virtual Machine".&lt;br /&gt;Make sure that you don't have the Ubuntu CD in your read DVD player. Click on "continue without disk".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5189522486/" title="vm2 by datacharmer, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1005/5189522486_d20055a877.jpg" width="500" height="361" alt="vm2" /&gt;&lt;/a&gt;&lt;br /&gt;Ignore the top options, and select "create a custom virtual machine".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188921765/" title="vm3 by datacharmer, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4085/5188921765_7660d8f8c1.jpg" width="500" height="361" alt="vm3" /&gt;&lt;/a&gt;&lt;br /&gt;Select the same operating system that was used for your base VM.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188921825/" title="vm4 by datacharmer, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4128/5188921825_1a1ac755be.jpg" width="500" height="363" alt="vm4" /&gt;&lt;/a&gt;&lt;br /&gt;When the summary shows up, choose "Customize settings".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5189522730/" title="vm5 by datacharmer, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1288/5189522730_3a43a9c712.jpg" width="500" height="361" alt="vm5" /&gt;&lt;/a&gt;&lt;br /&gt;Save the VM with a sensible name. Since you will be creating many of the same kind, choose a pattern that you can recognize. In this case, I used the base name with an additional letter at the end to identify the server.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188921945/" title="vm6 by datacharmer, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4129/5188921945_d5477a3cce.jpg" width="500" height="328" alt="vm6" /&gt;&lt;/a&gt;&lt;br /&gt;The disk is your main concern. The default settings want to create a 20 GB disk. Simply remove it.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5189522822/" title="vm7 by datacharmer, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4131/5189522822_4bfff6bd75.jpg" width="500" height="330" alt="vm7" /&gt;&lt;/a&gt;&lt;br /&gt;When asked if you want to get rid of the disk completely, say yes, "move it to the trash".&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;Now, &lt;b&gt;Very important&lt;/b&gt;, before you go to the next step. Use the command line, or a GUI, and copy the index .vmdk file from the base directory to the new virtual machine. I call it nd.vmdk (nd=new disk) but you can call it whatever you want. make sure that this file is not write protected.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188922073/" title="vm8 by datacharmer, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1033/5188922073_0ac717dc99.jpg" width="500" height="333" alt="vm8" /&gt;&lt;/a&gt;&lt;br /&gt;Add another disk. Here's the first trick part. By default, Fusion wants to recreate the same disk that you have just removed. But notice that there is a drop down menu on the right side of the panel. Click on "choose existing disk".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5189522948/" title="vm9 by datacharmer, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4128/5189522948_72aca65a69.jpg" width="500" height="349" alt="vm9" /&gt;&lt;/a&gt;&lt;br /&gt;Here you select the file that you have copied from the base directory. And now another tricky point. Make sure that you click on &lt;b&gt;"Share this virtual disk ..."&lt;/b&gt;, otherwise VMWare will make a copy of your original disk files.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188922225/" title="vm11 by datacharmer, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1271/5188922225_7315e67a5b.jpg" width="500" height="332" alt="vm11" /&gt;&lt;/a&gt;&lt;br /&gt;You can now change other parameters in the virtual machine, such as the amount of RAM and how many processors you want to use for it. I recommend unchecking the "connected" box next to the CDROM, to avoid a warning when more than a cloned VM work at the same time. You can always enable the CD later if you need it.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188922343/" title="vm12 by datacharmer, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1275/5188922343_13e6bf1c09.jpg" width="500" height="458" alt="vm12" /&gt;&lt;/a&gt;&lt;br /&gt;Now &lt;b&gt;Don't switch on your cloned virtual machine just yet&lt;/b&gt;. If you do, you get an incomprehensible message, where the VM complains about not being able to access the new disk file, while in reality it can't access the disks referred by that index file. This is where the precaution of write protecting the files comes handy. If you hadn't done that, the VM would access (and eventually modify) the virtual disk files, and possibly corrupt them. Instead, you need another step before having a functional clone.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5189523260/" title="vm13 by datacharmer, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1303/5189523260_9f36e1e6b0.jpg" width="500" height="470" alt="vm13" /&gt;&lt;/a&gt;&lt;br /&gt;You need to create a snapshot. Once you have done that, the VM will write to the snapshot files all the deltas between your read-only disks and your VM final status.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188922587/" title="vm14 by datacharmer, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1041/5188922587_9cf52619b5.jpg" width="500" height="456" alt="vm14" /&gt;&lt;/a&gt;&lt;br /&gt;You can call the snapshot whatever you like.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/datacharmer/5188922677/" title="vm15 by datacharmer, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1280/5188922677_d52e5e54de.jpg" width="500" height="345" alt="vm15" /&gt;&lt;/a&gt;&lt;br /&gt;Finally, you can run the virtual machine. If other virtual machines are running, it may warn you that some devices might not be available. Ignore this warning unless you know for sure that there is a unique resource that should not be shared (usually, there isn't).&lt;br /&gt;&lt;br /&gt;Your virtual machine is ready to run. If you need to create three identical servers to simulate a cluster, and the original VM has 4GB of occupied storage, the operation won't cost you 16 GB, but just a few dozen MB:&lt;br /&gt;&lt;pre&gt;$ du -sh ub_*/&lt;br /&gt; 21M ub_srv_10_10a.vmwarevm/&lt;br /&gt; 22M ub_srv_10_10b.vmwarevm/&lt;br /&gt; 21M ub_srv_10_10c.vmwarevm/&lt;br /&gt;3.9G ub_srv_10_base/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Part II - Use your virtual machines from the command line&lt;/h2&gt;Although VMWare Fusion is handy for creating virtual machines, and for using GUI-based operating systems, it is less than desirable when you have several virtual machines with only text interface, and you want to use them from the command line, the same way you would do in most real life administration or QA operations.&lt;br /&gt;&lt;br /&gt;No need for further hacking, in this case. You can manage your virtual machines from the command line, using an utility called &lt;b&gt;vmrun&lt;/b&gt;, which is located under /Library/Application Support/VMware Fusion/.&lt;br /&gt;You can read the full manual in a lengthy PDF document that is available online ( &lt;a href="http://www.vmware.com/pdf/vix160_vmrun_command.pdf"&gt;Using vmrun to Control Virtual Machines&lt;/a&gt;), but here's the short story.&lt;br /&gt;&lt;b&gt;vmrun&lt;/b&gt; can start and stop a virtual machine. You just need to use it when the VMWare Fusion application is closed. For example:&lt;br /&gt;&lt;pre&gt;$ vmrun start $HOME/vmware/vm/ub_srv_10_10a.vmwarevm/ub_srv_10_10a.vmx nogui&lt;br /&gt;2010-11-19 14:58:49 no printer configured or none available&lt;br /&gt;2010-11-19 14:58:49 adaptor daemon booted&lt;br /&gt;2010-11-19 14:58:49 connector "vmlocal" booted&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As part of my preparation of the virtual machine, I created a simple script that runs ifconfig and filters out the virtual machine IP to a file in the user's home.&lt;br /&gt;Using this information, I can then run the following commands:&lt;br /&gt;&lt;pre&gt;$ vmrun -gu qa -gp SECRETPWD &lt;b&gt;runProgramInGuest&lt;/b&gt; \&lt;br /&gt;   $HOME/vmware/vm/ub_srv_10_10a.vmwarevm/ub_srv_10_10a.vmx \&lt;br /&gt;   /home/qa/bin/get_ip&lt;br /&gt;&lt;br /&gt;$ vmrun -gu qa -gp SECRETPWD &lt;b&gt;copyFileFromGuestToHost&lt;/b&gt; \&lt;br /&gt;   $HOME/vmware/vm/ub_srv_10_10a.vmwarevm/ub_srv_10_10a.vmx \&lt;br /&gt;   /home/qa/myip ./server_a_ip&lt;br /&gt;&lt;br /&gt;$ cat server_a_ip &lt;br /&gt;192.168.235.144&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is just a simple example of what you can do. Once you have the IP address (which the DHCP server could change), you can connect to your virtual machine via ssh and do what you need. When you have finished, you can switch off the VM, again without need of using the GUI:&lt;br /&gt;&lt;pre&gt;$ vmrun stop ~/vmware/vm/ub_srv_10_10a.vmwarevm/ub_srv_10_10a.vmx 2010-11-19 15:11:25 adaptor daemon shut down&lt;br /&gt;2010-11-19 15:11:25 connector "vmlocal" shut down&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Happy (cloud) hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-6180621817315153146?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/6180621817315153146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=6180621817315153146' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6180621817315153146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6180621817315153146'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/how-to-create-private-cloud-in-your.html' title='How to create a private cloud in your laptop'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1286/5188933703_9c286ff58e_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-5554137590555661942</id><published>2010-11-12T14:55:00.000+01:00</published><updated>2010-11-12T14:55:33.170+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='filter'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='binary log'/><title type='text'>Filtering binary logs with MySQL Sandbox and replication</title><content type='html'>A few days ago, a friend of mine asked me if I knew of a way of filtering a bunch of binary logs, to extract only statements related to a single table. The task was about filtering a few hundred binary log files.&lt;br /&gt;&lt;br /&gt;It's a tricky problem. Even with my experience with regular expressions, I knew that using a script to extract statements related to a single table was going to be a nasty business.&lt;br /&gt;However, I know of an entity that can filter by table name efficiently, and that's the MySQL replication system. So I suggested using replication to a sandbox with a replicate-wild-do-table statement to get the job done.&lt;br /&gt;My friend was skeptical and did not want to go that way. I was busy writing an article for an Italian magazine and did not follow up immediately. But today, with the article safely in the editor's hands, I did a quick test, and guess what? It works! &lt;br /&gt;&lt;img alt="binary log filter" border="0" src="http://lh5.ggpht.com/_gVfZHGgf5LA/TN0_4bICi8I/AAAAAAAAA-0/1KYToAffDdA/s576/binlog_filter.png" title="binary log filter" /&gt;&lt;br /&gt;Here is a step-by-step procedure to do it. I started with a server built with &lt;a href="http://mysqlsandbox.net/"&gt;MySQL Sandbox&lt;/a&gt;, using MySQL 5.5.7. I used the &lt;a href="http://launchpad.net/test-db"&gt;employees test database&lt;/a&gt; to create a large enough binlog, and soon I had a database containing 160 MB of data and a binary log of about the same size.&lt;br /&gt;Then I decided that I wanted to filter the binlog, to get only statements about the &lt;i&gt;employees&lt;/i&gt; table. Thus, I issued this command:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$ make_sandbox 5.5.7 --sandbox_port=6000 \&lt;br /&gt;  --sandbox_directory=trans_repl \&lt;br /&gt;  -c log-slave-update \&lt;br /&gt;  -c replicate-wild-do-table=employees.employees \&lt;br /&gt;  -c log-bin=mysql-bin \&lt;br /&gt;  -c server-id=101&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The "-c" option transfers its argument to the sandbox configuration file. &lt;br /&gt;At the end of this operation, I had one server with the same version of the server that I had filled with the employee database. The server is ready to filter replicated streams, accepting only commands that affect the table 'employees' within the database 'employees'.&lt;br /&gt;&lt;br /&gt;The second step was to create an empty database in the second server, with the Innodb tables converted to BlackHole (to avoid wasting unnecessary space).&lt;br /&gt;&lt;br /&gt;Inside the first sandbox, I did this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$ ./my sqldump -B --no-data employees \&lt;br /&gt;  | perl -pe 's/=innodb/=blackhole/i' \&lt;br /&gt;  | ~/sandboxes/trans_repl/use&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Combining the flexibility of the sandbox with some command line skills, the operation requires just one command.&lt;br /&gt;Before starting the replication, I needed to avoid re-creating the tables, or my blackhole trick would have been useless. So I looked at the binary log, and found where the CREATE TABLE statements ended:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ ./my sqlbinlog ./data/mysql-bin.000001 |less&lt;br /&gt;BEGIN&lt;br /&gt;/*!*/;&lt;br /&gt;# at 3057&lt;br /&gt;#101112  9:48:45 server id 1  end_log_pos 3364  Query   thread_id=1     exec_time=0     error_code=0&lt;br /&gt;SET TIMESTAMP=1289551725/*!*/;&lt;br /&gt;INSERT INTO `departments` VALUES ('d001','Marketing'),('d002','Finance'),('d003','Human Resources'),('d004','Production'),('d005','Development'),('d006','Quality Management'),('d007','Sales'),('d008','Research'),('d009','Customer Service')/*!*/;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Armed with this knowledge, I logged in the second server and did the following:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;FLUSH BINARY LOGS; # to get a binlog with only the statements that I need&lt;br /&gt;&lt;br /&gt;CHANGE MASTER TO&lt;br /&gt;master_host='127.0.0.1',&lt;br /&gt;master_port=5570,&lt;br /&gt;master_user='msandbox',&lt;br /&gt;master_password='msandbox',&lt;br /&gt;master_log_file='mysql-bin.000001',&lt;br /&gt;master_log_pos=3057;    # this is the position after all the CREATE TABLE&lt;br /&gt;                        # statements in the master&lt;br /&gt;START SLAVE;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;After a few seconds, I issued a "SHOW SLAVE STATUS". All was OK.&lt;br /&gt;I flushed the logs again and inspected the second binary log. As expected, it contained only the statements related to the employees table.&lt;br /&gt;Total cost of the operation: 5 minutes. Way quicker than writing this report!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-5554137590555661942?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/5554137590555661942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=5554137590555661942' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5554137590555661942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/5554137590555661942'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/filtering-binary-logs-with-mysql.html' title='Filtering binary logs with MySQL Sandbox and replication'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_gVfZHGgf5LA/TN0_4bICi8I/AAAAAAAAA-0/1KYToAffDdA/s72-c/binlog_filter.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-6244795590004690501</id><published>2010-11-11T23:17:00.002+01:00</published><updated>2010-11-11T23:22:37.192+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='Birmingham'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='UK'/><category scheme='http://www.blogger.com/atom/ns#' term='IOUG'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='UKOUG'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Speaking at the UK Oracle User Group conference - Birmingham</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.ukoug.org/other/?t=mysql"&gt;&lt;img alt="UKOUG Conference" border="0" src="http://lh5.ggpht.com/_gVfZHGgf5LA/TNxop4pNJCI/AAAAAAAAA-w/OPbu6dq1ViE/UKOUG_conf_2010.png" title="UKOUG Conference" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;Back to the conference circuit after some rest.&lt;br /&gt;On December 1st I will be speaking under my new affiliation at Continuent in the &lt;a href="http://www.ukoug.org/other/?t=mysql"&gt;MySQL track&lt;/a&gt; at the &lt;a href="http://techandebs.ukoug.org/default.asp?p=5450"&gt;UKOUG conference&lt;/a&gt;. My topic is &lt;a href="http://techandebs.ukoug.org/default.asp?p=5434&amp;amp;dlgact=shwprs&amp;amp;prs_prsid=5708&amp;amp;day_dayid=47"&gt;MySQL - Features for the enterprise&lt;/a&gt; and it will basically cover the main features of MySQL 5.5.&lt;br /&gt;This conference is the largest Oracle related event in Europe, and it is organized by users for other users. This year for the first time the conference hosts a MySQL dedicated track. &lt;br /&gt;It is a sort of epidemic. Most of the important Oracle events have now some MySQL content, or a full track. I see this as a great opportunity for both classic MySQL and Oracle users to meet each other and find common business ground for the future.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-6244795590004690501?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/6244795590004690501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=6244795590004690501' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6244795590004690501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6244795590004690501'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/speaking-at-uk-oracle-user-group.html' title='Speaking at the UK Oracle User Group conference - Birmingham'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_gVfZHGgf5LA/TNxop4pNJCI/AAAAAAAAA-w/OPbu6dq1ViE/s72-c/UKOUG_conf_2010.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-7211354341709462617</id><published>2010-11-04T01:19:00.000+01:00</published><updated>2010-11-04T01:19:52.578+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='semisynch'/><title type='text'>Testing MySQL 5.5 semi-synchronous replication</title><content type='html'>A few days ago I saw an article about &lt;a href="http://www.bluegecko.net/mysql/semi-synchronous-replication-in-mysql-5-5/"&gt;Semi-Synchronous Replication in MySQL 5.5&lt;/a&gt;. It asks questions, and doesn't give answers beyond gut feeling. So I thought that I would do some practical testing of this new feature.&lt;br /&gt;Before we go that way, though, let's revisit the theory.&lt;br /&gt;&lt;h3&gt;How semi-synchronous replication works&lt;/h3&gt;&lt;img border="0" src="http://lh6.ggpht.com/_gVfZHGgf5LA/TNHwuuWOkgI/AAAAAAAAA-k/kdhEL_WL1do/s640/scaling_with_replication.065.jpg" /&gt;&lt;br /&gt;&lt;i&gt;Figure 1. A transaction with regular replication&lt;/i&gt;&lt;br /&gt;With regular replication, you send a transaction to the master (1). When the &lt;code&gt;COMMIT&lt;/code&gt; is received, the master executes it (2), and if successful it logs the transaction to the binary log (3). The the master answers the client request (4) with a successful result. In the meantime, the slaves replicate the record (5).&lt;br /&gt;What happens if the master crashes after point #4 and before a slave has had a chance of getting the data in point #5?&lt;br /&gt;The client will have a result for that transaction, but that data is lost, because it has never reached one slave. &lt;br /&gt;&lt;br /&gt;&lt;img border="0" src="http://lh6.ggpht.com/_gVfZHGgf5LA/TNHwuuDum0I/AAAAAAAAA-o/kSWM5ux2f6c/s640/scaling_with_replication.066.jpg" /&gt;&lt;br /&gt;&lt;i&gt;Figure 2. A transaction with semi-synchronous replication&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Let's see the same scenario with semi-synchronous replication. All is the same until point #3. Then, things change. The master does not return to the client. Instead, it alerts the slave that a transaction is available (4). The slave gets it and stores it to the relay log (5). Without further action, the slave tells the master that the transaction was received (6) and only then the master returns the result to the client (7).&lt;br /&gt;What is the benefit? If the master crashes, the transaction is lost. but the client does not get the false information that the transaction was stored. Instead, if the master crashes before it returns the result to the client, the client gets an error, and knows that that transaction needs to be reworked when a new master is back.&lt;br /&gt;&lt;h3&gt;Semi-synchronous replication in practice&lt;/h3&gt;Now, the practicalities.&lt;br /&gt;How do you tell if semi-synchronous replication is working? If you leave the default timeout of 10 seconds, you have an immediate clue that something is wrong when a query takes too long to return. Investigation is possible by looking at the GLOBAL STATUS variables.&lt;br /&gt;&lt;code&gt;Rpl_semi_sync_master_status&lt;/code&gt; tells you if the master is ready for semi-synchronous replication.&lt;br /&gt;&lt;code&gt;Rpl_semi_sync_master_yes_tx&lt;/code&gt; is the number of positive transactions that were delivered using semi-synchronous replication.&lt;br /&gt;&lt;code&gt;Rpl_semi_sync_master_no_tx&lt;/code&gt; is the number of failed attempts at delivering a transaction via semi-synchronous replication. When that happens, &lt;code&gt;Rpl_semi_sync_master_status&lt;/code&gt; becomes "OFF", and you need investigating.&lt;br /&gt;&lt;br /&gt;The important thing to understand about this feature is that semi-synchronous replication does not guarantee that your transaction is executed in the slave. It will only tell you that the data has been transferred to the slave relay log. It can still happen that the transaction fails to execute on the slave (which could be either a bug in your application or a bug in MySQL replication). But this is not a cluster. Don't expect a two-phase commit.&lt;br /&gt;&lt;h3&gt;Testing semi-synchronous replication&lt;/h3&gt;If you want to test this feature without suffering too much, you can use a tarball binary and &lt;a href="http://mysqlsandbox.net/"&gt;MySQL Sandbox&lt;/a&gt;. Once you have installed MySQL Sandbox and have downloaded the server tarball, you can install a test replication system with&lt;br /&gt;&lt;pre&gt;&lt;code&gt;make_replication_sandbox --how_many_slaves=4 /path/to/mysql-5.5.6-yourOS.tar.gz&lt;/code&gt;&lt;/pre&gt;This will create a system with 1 master and 4 slaves.&lt;br /&gt;The Sandbox has a shortcut to install the plugin quickly and painlessly:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;sbtool -o plugin --plugin=semisynch -s $HOME/sandboxes/rsandbox_5_5_6&lt;/code&gt;&lt;/pre&gt;Now you will have the semi-synchronous plugin installed in the master and all the slaves. For our tests, we will make a shell script, an easy task thanks to the sandbox utilities.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;echo "disabling semi-synch replication in all slaves except 1"&lt;br /&gt;./s1 -e 'set global rpl_semi_sync_slave_enabled=1'&lt;br /&gt;./s1 -e 'slave stop io_thread; slave start'&lt;br /&gt;&lt;br /&gt;for E in 2 3 4&lt;br /&gt;do&lt;br /&gt;    ./s$E -e 'set global rpl_semi_sync_slave_enabled=0'&lt;br /&gt;    ./s$E -e 'slave stop io_thread; slave start'&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# this query will show the main variables that tell&lt;br /&gt;# if semi-synch replication is working&lt;br /&gt;#&lt;br /&gt;Q1='select variable_name, variable_value'&lt;br /&gt;Q2='from information_schema.global_status'&lt;br /&gt;Q3='where variable_name in'&lt;br /&gt;Q4='("RPL_SEMI_SYNC_MASTER_YES_TX", "RPL_SEMI_SYNC_MASTER_NO_TX")'&lt;br /&gt;I_S_Q="$Q1 $Q2 $Q3 $Q4"&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "creating a table. it should replicate through the semi-synch"&lt;br /&gt;./m -vvv -e 'create table test.t1( i int)'&lt;br /&gt;./m -e "$I_S_Q"&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "inserting a record. The number of 'YES' should increase"&lt;br /&gt;./m -e 'insert into test.t1 values (1)'&lt;br /&gt;./m -e "$I_S_Q"&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "disabling semi-synch replication in slave 1"&lt;br /&gt;./s1 -e 'set global rpl_semi_sync_slave_enabled=0'&lt;br /&gt;./s1 -e 'slave stop io_thread; slave start'&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "enabling semi-synch replication in slave 3"&lt;br /&gt;./s3 -e 'set global rpl_semi_sync_slave_enabled=1'&lt;br /&gt;./s3 -e 'slave stop io_thread; slave start'&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "inserting a record. The number of 'YES' should increase"&lt;br /&gt;./m -e 'insert into test.t1 values (2)'&lt;br /&gt;./m -e "$I_S_Q"&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "disabling semi-synch replication in slave 3"&lt;br /&gt;./s3 -e 'set global rpl_semi_sync_slave_enabled=0'&lt;br /&gt;./s3 -e 'slave stop io_thread; slave start'&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "inserting a record. The number of 'NO' should increase"&lt;br /&gt;./m -vvv -e 'insert into test.t1 values (3)'&lt;br /&gt;./m -e "$I_S_Q"&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "enabling semi-synch replication in slave 2"&lt;br /&gt;./s2 -e 'set global rpl_semi_sync_slave_enabled=1'&lt;br /&gt;./s2 -e 'slave stop io_thread; slave start'&lt;br /&gt;&lt;br /&gt;echo ""&lt;br /&gt;echo "inserting a record. The number of 'YES' should increase"&lt;br /&gt;./m -e 'insert into test.t1 values (4)'&lt;br /&gt;./m -e "$I_S_Q"&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;This script will first disable semi-synchronous replication in all the slaves except one. Then it will create a table, and check for the telling status variables.&lt;br /&gt;This should work quickly and without problems. Then it will disable the plugin on the only slave that was active, and enable another slave instead. &lt;br /&gt;Inserting a record on the master will work again quickly, as the newly enabled slave will get the record immediately.&lt;br /&gt;Then the slave gets disabled, and we can witness what happens. The query takes a bit longer than 10 seconds, and the status variable tells us that semi-synchronous replication has failed.&lt;br /&gt;We finally enable yet another slave, and when we try a further insertion, we can see that the semi-synchronous replication has resumed.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Very important:&lt;/b&gt;&lt;br /&gt;To enable or disable semi-synchronous replication on a slave it is not enough to set the appropriate variable. You need also to restart the slave by issuing a &lt;code&gt;STOP SLAVE IO_THREAD&lt;/code&gt; followed by a &lt;code&gt;START SLAVE&lt;/code&gt; commands.&lt;br /&gt;&lt;br /&gt;Here is a sample run:&lt;br /&gt;&lt;pre&gt;disabling semi-synch replication in all slaves except 1&lt;br /&gt;&lt;br /&gt;creating a table. it should replicate through the semi-synch&lt;br /&gt;--------------&lt;br /&gt;create table test.t1( i int)&lt;br /&gt;--------------&lt;br /&gt;&lt;br /&gt;Query OK, 0 rows affected (0.87 sec)&lt;br /&gt;&lt;br /&gt;Bye&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| variable_name               | variable_value |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_NO_TX  | 0              |&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_YES_TX | 1              |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;&lt;br /&gt;inserting a record. The number of 'YES' should increase&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| variable_name               | variable_value |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_NO_TX  | 0              |&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_YES_TX | 2              |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;&lt;br /&gt;disabling semi-synch replication in slave 1&lt;br /&gt;&lt;br /&gt;enabling semi-synch replication in slave 3&lt;br /&gt;&lt;br /&gt;inserting a record. The number of 'YES' should increase&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| variable_name               | variable_value |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_NO_TX  | 0              |&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_YES_TX | 3              |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;&lt;br /&gt;disabling semi-synch replication in slave 3&lt;br /&gt;&lt;br /&gt;inserting a record. The number of 'NO' should increase&lt;br /&gt;--------------&lt;br /&gt;insert into test.t1 values (3)&lt;br /&gt;--------------&lt;br /&gt;&lt;br /&gt;Query OK, 1 row affected (10.12 sec)&lt;br /&gt;&lt;br /&gt;Bye&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| variable_name               | variable_value |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_NO_TX  | 1              |&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_YES_TX | 3              |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;&lt;br /&gt;enabling semi-synch replication in slave 2&lt;br /&gt;&lt;br /&gt;inserting a record. The number of 'YES' should increase&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| variable_name               | variable_value |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_NO_TX  | 1              |&lt;br /&gt;| RPL_SEMI_SYNC_MASTER_YES_TX | 4              |&lt;br /&gt;+-----------------------------+----------------+&lt;br /&gt;&lt;/pre&gt;Using the above steps, you should be able to use semi-synchronous replication and do some basic monitoring to make sure that it works as expected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-7211354341709462617?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/7211354341709462617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=7211354341709462617' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7211354341709462617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/7211354341709462617'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/testing-mysql-55-semi-synchronous.html' title='Testing MySQL 5.5 semi-synchronous replication'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_gVfZHGgf5LA/TNHwuuWOkgI/AAAAAAAAA-k/kdhEL_WL1do/s72-c/scaling_with_replication.065.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-1397469100146388378</id><published>2010-11-02T15:19:00.000+01:00</published><updated>2010-11-02T15:19:24.308+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qa'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='continuent'/><category scheme='http://www.blogger.com/atom/ns#' term='jobs'/><title type='text'>QA at Continuent. A serendipitous job.</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://continuent.com/"&gt;&lt;img alt="Unexpected road" border="0" src="http://lh5.ggpht.com/_gVfZHGgf5LA/TM_AE6iOpxI/AAAAAAAAA-g/YPAaRSlI_zE/unexpected_road.png" title="Unexpected road" width="300" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;A few days ago, I &lt;a href="http://blogs.sun.com/datacharmer/entry/into_the_sunset"&gt;left the MySQL team at Oracle&lt;/a&gt;, after more than 4 years of work dedicated mostly to the MySQL community.&lt;br /&gt;Someone will probably remember that, when I joined MySQL in 2006, I started my work in the QA team. It was no coincidence. My previous work as a consultant was very much focused on database development quality, even when my customers had approached me for different reasons. &lt;br /&gt;Let's be frank. I am a minority. It's not common to find someone who is passionate about QA. I am aware of being a rare bird, who likes testing and bug searching, and doing all the little steps that all together improve the overall quality of a software system.&lt;br /&gt;I had been thinking about my passion lately, and I often caught myself thinking why in my job at MySQL I let things slip away so much from my ambition of tackling some hard technical problems. &lt;br /&gt;I was more or less in this frame of mind when I met by chance an old acquaintance, Robert Hodges, CEO of &lt;a href="http://continuent.com/"&gt;Continuent&lt;/a&gt; and a fine technologist whom I respect and admire. And I was astonished to hear him asking me if I knew a good candidate for a position of QA manager for Continuent.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;You can guess the rest of the story. I told him that I indeed had a candidate, and the next day we went to dinner together, and talked the most hackish and refreshing talk that I have had in years with Ed Archibald, the CTO (oh, and the steaks were great too!) &lt;br /&gt;A few days after that, Robert and Ed organized a demo of Continuent technology for me, and I was hooked.&lt;br /&gt;&lt;br /&gt;There was, indeed, an uncommon problem to solve. I had received offers for very good positions at three other companies, and one more had asked me if I wanted to consider working for them. As all the offering parts are friends, this fact did put me in a difficult position. Every offer was very intriguing and exciting, and in the end I had to take a choice, leaving one happy and three disappointed friends in the field. After careful choice, I chose Continuent, where I will start as &lt;b&gt;Director of Quality Assurance&lt;/b&gt; on November 15&lt;sup&gt;th&lt;/sup&gt;. &lt;br /&gt;Fortunately for me, the three other friends are real friends, and they took the refusal graciously. They knew from the beginning that they had competition, and they knew that they could win or lose for reasons that they could not fully control. And indeed the main reason for choosing Continuent is the challenge of developing a beautiful technology that will eventually take the world by storm. (Or so it's the general plan. It's too early to make claims, as I haven't started getting acquainted with the technology yet, but it feels good).&lt;br /&gt;&lt;br /&gt;What now? I have some tentative plans that I need to consolidate in the near future:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Taking some vacation. I am already one day into this first part;&lt;/li&gt;&lt;li&gt;Getting familiar with the technology that I will help improving;&lt;/li&gt;&lt;li&gt;Getting acquainted with my new colleagues, for which I will have a splendid occasion at the company meeting that will happen soon in Stuttgart;&lt;/li&gt;&lt;li&gt;Learning some new technology, both in development and in a more strict QA field;&lt;/li&gt;&lt;li&gt;Setting up my new laptop, which will hopefully come before I start the new job;&lt;/li&gt;&lt;li&gt;Talking at conferences. I have already committed to talking at the UKOUG in Birmingham, on December 1&lt;sup&gt;st&lt;/sup&gt;, and more will come.&lt;/li&gt;&lt;li&gt;Resuming my blogging at full speed. I have a mental drawer full of ideas, and I only need to transfer them to the keyboard.&lt;/li&gt;&lt;/ul&gt;And probably I will also start playing with the new technologies that I have been reading about in the last months but I haven't had time to pursue. Either way, I feel refreshed and ready for the next battle.&lt;br /&gt;Thanks, Continuent, for this great opportunity!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-1397469100146388378?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/1397469100146388378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=1397469100146388378' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1397469100146388378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/1397469100146388378'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/qa-at-continuent-serendipitous-job.html' title='QA at Continuent. A serendipitous job.'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_gVfZHGgf5LA/TM_AE6iOpxI/AAAAAAAAA-g/YPAaRSlI_zE/s72-c/unexpected_road.png' height='72' width='72'/><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-6964367830079571447</id><published>2010-11-01T19:51:00.004+01:00</published><updated>2010-11-01T20:05:22.807+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='storage engine'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='UDF'/><category scheme='http://www.blogger.com/atom/ns#' term='review'/><category scheme='http://www.blogger.com/atom/ns#' term='extending'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Book review: MySQL 5.1 plugin development</title><content type='html'>&lt;table border="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.packtpub.com/mysql-5-1-plugins-development/book"&gt;&lt;img alt="MySQL 5.1 Plugin Development" border="0" src="http://lh4.ggpht.com/_gVfZHGgf5LA/TM8JfBvAIII/AAAAAAAAA-c/zKefsdVOmHo/mysql_5_1_plugin_development_small.png" title="MySQL 5.1 Plugin Development" /&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;a href="http://www.packtpub.com/mysql-5-1-plugins-development/book"&gt;MySQL 5.1 Plugin Development&lt;/a&gt;, &lt;br /&gt;by Sergei Golubchik and Andrew Hutchings.&lt;br /&gt;Packt Publishing, 2010.&lt;br /&gt;&lt;i&gt;Executive summary: Highly recommended. If you want to develop MySQL extensions, buy this book. It's a must, written by two expert professionals who probably know more than anyone else on this matter. The book is full of practical examples explained with the theoretical information necessary to make it stick.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;This book fills a gap in the world of MySQL documentation. Although the MySQL docs are extensive and thorough, to the point that sometimes you wished that the writers were less verbose and stick more to the topic, when it comes to the plugin architecture, there are still more some unanswered questions. I guess that the ones who have implemented MySQL extensions so far have read the code, more than the documentation.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;But, back to the point. The void is filled now, and in such a wonderful way! I have to disclose that I was the reviewer of this book, and while this fact puts me in a conflicting position when it comes to a review, it has also given me inner reason for praise, beyond the experience of a regular reader. The people who have worked with me will know that I am hard to please, and so my review was peppered with suggestions for improvements that, I admit it, made the authors' life quite difficult. I mostly complained that some of the examples proposed for each chapter were not enough useful and interesting. In short, there was not enough incentive for the reader to start coding immediately. I am glad to report that the authors were very responsive, and, rather than being annoyed by my demands, did work enthusiastically at the examples in the book until they became a true gem in this category. This book will surprise you for its practical approach, when it guides you through the examples, until you end up with a working extension.&lt;br /&gt;The first chapter is probably the part that will save many hours of attempts to everyone who wants to build a plugin. In that chapter the authors explain how to build the different types of plugins in several operating systems. If you have ever tried to build a plugin, you will appreciate this chapter.&lt;br /&gt;The book's body covers every type of plugin that you can create in MySQL, from the classic UDF to the more recent storage engine. For each chapter, you will have code ready to compile and try on your own, and the line-by-line explanation of what that code does, and why it was written the way it is.&lt;br /&gt;Whenever the code is less than intuitive, the authors take care of it with additional theoretical and practical explanation, making sure that the reader is fully informed on the topic, and can complete the task effectively.&lt;br /&gt;Summing up, this is not a book for the idle reader. It's a a practical help for the doers, the ones who want to get the job done, and need guidance through the maze of the MySQL plugin protocol.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update.&lt;/b&gt; There is also a &lt;a href="http://books.slashdot.org/story/10/11/01/1338249/MySQL-51-Plugin-Development"&gt;review at Slashdot&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16959946-6964367830079571447?l=datacharmer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://datacharmer.blogspot.com/feeds/6964367830079571447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16959946&amp;postID=6964367830079571447' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6964367830079571447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16959946/posts/default/6964367830079571447'/><link rel='alternate' type='text/html' href='http://datacharmer.blogspot.com/2010/11/book-review-mysql-51-plugin-development.html' title='Book review: MySQL 5.1 plugin development'/><author><name>Giuseppe Maxia</name><uri>https://profiles.google.com/104662922458927529001</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-81_PmDVG6gg/AAAAAAAAAAI/AAAAAAAABK4/IDF97xMQk7U/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_gVfZHGgf5LA/TM8JfBvAIII/AAAAAAAAA-c/zKefsdVOmHo/s72-c/mysql_5_1_plugin_development_small.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16959946.post-784289846936244192</id><published>2010-10-09T23:53:00.000+02:00</published><updated>2010-10-09T23:53:37.063+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='opensqlcamp'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='speaking'/><category scheme='http://www.blogger.com/atom/ns#' term='integrity'/><title type='text'>My wish list for OpenSQLCamp, Boston 2010</title><con
