<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Andrew Morgan's MySQL Cluster Database Blog &#187; MySQL Cluster</title>
	<atom:link href="http://www.clusterdb.com/category/mysql-cluster/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.clusterdb.com</link>
	<description>MySQL Cluster database &#38; MySQL Replication</description>
	<lastBuildDate>Wed, 01 Feb 2012 18:35:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>MySQL Cluster 7.1.19 is available to download</title>
		<link>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-9-is-available-to-download/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-cluster-7-1-9-is-available-to-download</link>
		<comments>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-9-is-available-to-download/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 15:04:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.1]]></category>
		<category><![CDATA[MySQL Cluster CGE]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2200</guid>
		<description><![CDATA[The binary version for MySQL Cluster 7.1.19 has now been made available at http://www.mysql.com/downloads/cluster/ (GPL version) or https://support.oracle.com/ (commercial version) A description of all of the changes (fixes) that have gone into MySQL Cluster 7.1.19 (compared to 7.1.18) will appear in the 7.1.19 Change log.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png"><img class="alignright size-full  wp-image-919" title="mysql-cluster-logo-150x105" src="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png" alt="" width="150" height="105" /></a> The binary version for MySQL Cluster 7.1.19 has now been made available at <a href="http://www.mysql.com/downloads/cluster/" target="_blank">http://www.mysql.com/downloads/cluster/</a> (GPL version) or <a href="https://support.oracle.com/" target="_blank">https://support.oracle.com/</a> (commercial version)</p>
<p>A description of all of the changes (fixes) that have gone into MySQL Cluster 7.1.19 (compared to 7.1.18) will appear in the <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-news-5-1-56-ndb-7-1-19.html" target="_blank">7.1.19 Change log</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-9-is-available-to-download/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Chance to give your views on MySQL Cluster 7.2 content</title>
		<link>http://www.clusterdb.com/mysql-cluster/cluster_7_2_poll/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cluster_7_2_poll</link>
		<comments>http://www.clusterdb.com/mysql-cluster/cluster_7_2_poll/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 14:17:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.2]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2191</guid>
		<description><![CDATA[The MySQL Cluster 7.2 Development Milestone Release has been out for a while now and we&#8217;d love to hear which are your favourite features &#8211; it takes just a few seconds to complete the Quick-Poll. It should literally take seconds to complete and will provide us with valuable feedback on the kind of features are [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clusterdb.com/wp-content/uploads/2012/01/questionnaire.jpg"><img class="alignright size-medium wp-image-2192" title="Quick Poll" src="http://www.clusterdb.com/wp-content/uploads/2012/01/questionnaire-300x298.jpg" alt="MySQL Cluster 7.2 Quick Poll" width="300" height="298" /></a>The <a title="MySQL Cluster 7.2 Development Milestone Release" href="https://dev.mysql.com/tech-resources/articles/mysql-cluster-7.2.html" target="_blank">MySQL Cluster 7.2 Development Milestone Release</a> has been out for a while now and we&#8217;d love to hear which are your favourite features &#8211; it takes just a few seconds to <a title="MySQL Cluster 7.2 Quick Poll" href="https://dev.mysql.com/tech-resources/quickpolls/" target="_blank">complete the Quick-Poll</a>. It should literally take seconds to complete and will provide us with valuable feedback on the kind of features are most useful &#8211; so that we can build more of them in the future!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/cluster_7_2_poll/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Cluster Evaluation Guide &#8211; refreshed for Cluster 7.2 DMR</title>
		<link>http://www.clusterdb.com/mysql-cluster/mysql-cluster-evaluation-guide-refreshed-for-cluster-7-2-dmr/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-cluster-evaluation-guide-refreshed-for-cluster-7-2-dmr</link>
		<comments>http://www.clusterdb.com/mysql-cluster/mysql-cluster-evaluation-guide-refreshed-for-cluster-7-2-dmr/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 16:41:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.2]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2185</guid>
		<description><![CDATA[ There is an updated version of the MySQL Cluster Evaluation Guide to go with the MySQL Cluster 7.2 Development Milestone Release. The purpose of this guide is to enable you to efficiently evaluate the MySQL Cluster database and determine if it is the right choice for your application, whether as part of a new project [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png"><img class="alignright size-full wp-image-919" title="mysql-cluster-logo-150x105" src="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png" alt="" width="150" height="105" /></a> There is an updated version of the <a href="http://dev.mysql.com/downloads/MySQL_Cluster_72_DMR_EvaluationGuide.pdf" target="_blank">MySQL Cluster Evaluation Guide to go with the MySQL Cluster 7.2 Development Milestone Release</a>.</p>
<p>The purpose of this guide is to enable you to efficiently evaluate the MySQL<br />
Cluster database and determine if it is the right choice for your application,<br />
whether as part of a new project or an upgrade to an existing service.<br />
This guide presents a brief overview of the MySQL Cluster database and new<br />
features in the latest 7.2 Development Milestone Release, and then discusses:</p>
<ul>
<li>Considerations before initiating an evaluation</li>
<li>Evaluation best practices</li>
<li>Configuration options and sanity checking</li>
<li>Troubleshooting</li>
</ul>
<p>By following the recommendations in this Guide, you will be able to quickly and<br />
effectively evaluate the MySQL Cluster 7.2 Development Milestone Release<br />
(DMR).</p>
<p>Please note that the MySQL Cluster 7.2 Development Milestone is not a currently<br />
production-ready release. It is published to provide a preview of new features that<br />
are planned, but not committed, for the next production-ready “General<br />
Availability” release of MySQL Cluster.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/mysql-cluster-evaluation-guide-refreshed-for-cluster-7-2-dmr/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Cluster 7.1.18 is available to download</title>
		<link>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-18-is-available-to-download/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-cluster-7-1-18-is-available-to-download</link>
		<comments>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-18-is-available-to-download/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 10:32:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.1]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2178</guid>
		<description><![CDATA[The binary version for MySQL Cluster 7.1.18 has now been made available at http://www.mysql.com/downloads/cluster/ (GPL version) or https://support.oracle.com/ (commercial version) A description of all of the changes (fixes) that have gone into MySQL Cluster 7.1.18 (compared to 7.1.17) will appear in the 7.1.18 Change log soon.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png"><img class="alignright size-full  wp-image-919" title="mysql-cluster-logo-150x105" src="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png" alt="" width="150" height="105" /></a><br />
The binary version for MySQL Cluster 7.1.18 has now been made available at <a href="http://www.mysql.com/downloads/cluster/" target="_blank">http://www.mysql.com/downloads/cluster/</a> (GPL version) or <a href="https://support.oracle.com/" target="_blank">https://support.oracle.com/</a> (commercial version)</p>
<p>A description of all of the changes (fixes) that have gone into MySQL Cluster 7.1.18 (compared to 7.1.17) will appear in the <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-news-5-1-56-ndb-7-1-18.html" target="_blank">7.1.18 Change log</a> soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-18-is-available-to-download/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enhanced conflict resolution with MySQL Cluster active-active replication</title>
		<link>http://www.clusterdb.com/mysql-cluster/enhanced-conflict-resolution-with-mysql-cluster-active-active-replication/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=enhanced-conflict-resolution-with-mysql-cluster-active-active-replication</link>
		<comments>http://www.clusterdb.com/mysql-cluster/enhanced-conflict-resolution-with-mysql-cluster-active-active-replication/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 20:09:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.2]]></category>
		<category><![CDATA[MySQL Cluster CGE]]></category>
		<category><![CDATA[MySQL Replication]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2141</guid>
		<description><![CDATA[Part of the latest MySQL Cluster Development Milestone Release (MySQL Cluster 7.2.1 &#8211; select the &#8220;Development Release&#8221; tab at http://dev.mysql.com/downloads/cluster/#downloads) is a couple of enhancements to the conflict detection and resolution mechanism for active-active (multi-master) replication. While MySQL Cluster has had conflict detection for years it has now been made much more complete and a [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_2152" class="wp-caption alignright" style="width: 309px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/11/ReflectingGCI_small.gif"><img class="size-full wp-image-2152" title="ReflectingGCI_small" src="http://www.clusterdb.com/wp-content/uploads/2011/11/ReflectingGCI_small.gif" alt="" width="299" height="231" /></a><p class="wp-caption-text">Detecting conflicts</p></div>
<p>Part of the latest MySQL Cluster Development Milestone Release (MySQL Cluster 7.2.1 &#8211; select the &#8220;Development Release&#8221; tab at <a title="MySQL Cluster downloads" href="http://dev.mysql.com/downloads/cluster/#downloads" target="_new">http://dev.mysql.com/downloads/cluster/#downloads</a>) is a couple of enhancements to the conflict detection and resolution mechanism for active-active (multi-master) replication. While MySQL Cluster has had conflict detection for years it has now been made much more complete and a lot easier to use:</p>
<ul>
<li>No changes needed to the application schema</li>
<li>Entire conflicting transaction is rolled back together with any dependent transactions</li>
</ul>
<p>The focus of this post will be to step through how to use this feature &#8211; while it will also attempt to explain how it works at a high level, you should refer to the following posts for the design details and philosophy: <a title="Eventual consistency with MySQL" href="http://messagepassing.blogspot.com/2011/10/eventual-consistency-with-mysql.html" target="_new">Eventual consistency with MySQL</a> &amp; <a title="MySQL Clsuter, Eventual Consistency - detecting conflicts" href="http://messagepassing.blogspot.com/2011/10/eventual-consistency-detecting.html" target="_new">Eventual Consistency &#8211; detecting conflicts</a>.</p>
<h2>What is a conflict?</h2>
<p>MySQL Cluster allows bi-directional replication between two (or more) clusters. Replication within each cluster is synchronous but between clusters it is asynchronous which means the following scenario is possible:</p>
<table summary="Active-Active asynchronous replication can lead to inconsistencies between databases" width="260" border="1" align="center">
<caption align="center">Conflict with asynchronous replication</caption>
<tbody>
<tr>
<th scope="col" align="center" width="80">Site A</th>
<th scope="col" align="center" width="100">Replication</th>
<th scope="col" align="center" width="80">Site B</th>
</tr>
<tr>
<td align="center">x == 10</td>
<td></td>
<td align="center">x == 10</td>
</tr>
<tr>
<td align="center">x = 11</td>
<td></td>
<td align="center">x = 20</td>
</tr>
<tr>
<td></td>
<td align="center">&#8211; x=11 &#8211;&gt;</td>
<td align="center">x == 11</td>
</tr>
<tr>
<td align="center">x==20</td>
<td align="center">&lt;&#8211; x=20 &#8211;</td>
<td></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>In this example a value (column for a row in a table) is set to 11 on site A and the change is queued for replication to site B. In the mean time, an application sets the value to 20 on site B and that change is queued for replication to site A. Once both sites have received and applied the replicated change from the other cluster site A contains the value 20 while site B contains 11 &#8211; in other words the databases are now inconsistent.</p>
<h2>How MySQL Cluster 7.2 implements eventual consistency</h2>
<p>There are two phases to establishing consistency between both clusters after an inconsistency has been introduced:</p>
<ol>
<li>Detect that a conflict has happened</li>
<li>Resolve the inconsistency</li>
</ol>
<h3>Detecting the conflict</h3>
<p>The following animation illustrates how MySQL Cluster 7.2 detects that an inconsistency has been introduced by the asynchronous, active-active replication:</p>
<div id="attachment_2149" class="wp-caption alignnone" style="width: 610px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/11/ReflectingGCI1.gif"><img class="size-full wp-image-2149" title="ReflectingGCI" src="http://www.clusterdb.com/wp-content/uploads/2011/11/ReflectingGCI1.gif" alt="" width="600" height="463" /></a><p class="wp-caption-text">Detecting conflicts</p></div>
<p>While we typically consider the 2 clusters in an active-active replication configuration to be peers, in this case we designate one to be the primary and the other the secondary. Reads and writes can still be sent to either cluster but it is the responsibility of the primary to identify that a conflict has arisen and then remove the inconsistency.</p>
<p>A logical clock is used to identify (in relative terms) when a change is made on the primary &#8211; for those who know something of the MySQL Cluster internals, we use the index of the Global Checkpoint that the update is contained in. For all tables that have this feature turned on, an extra, hidden column is automatically added on the primary &#8211; this represents the value of the logical clock when the change was made.</p>
<p>Once the change has been applied on the primary, there is a &#8220;window of conflict&#8221; for the effected row(s) during which if a different change is made to the same row(s) on the secondary then there will be an inconsistency. Once the slave on the secondary has applied the change from the primary, it will send a replication event back to the slave on the primary, containing the primary&#8217;s clock value associated with the changes that have just been applied on the secondary. (Remember that the clock is actually the Global Checkpoint Index and so this feature is sometimes referred to as Reflected GCI). Once the slave on the primary has received this event, it knows that all changes tagged with a clock value no later than the reflected GCI are now safe &#8211; the window of conflict has closed.</p>
<p>If an application modifies this same row on the secondary before the replication event from the primary was applied then it will send an associated replication event to the slave on the primary <strong>before</strong> it reflects the new GCI. The slave on the primary will process this replication event and compare the clock value recorded with the effected rows with the latest reflected GCI; as the clock value for the conflicting row is higher the primary recognises that a conflict has occured and will launch the algorithm to resolve the inconsistency.</p>
<h3>Resolving the inconsistency</h3>
<p>In earlier releases of MySQL Cluster (or if choosing to use the original algorithm in MySQL Cluster 7.2) you had a choice of simply flagging the primary key of the conflicting rows or backing out one of the changes to the conflicting rows. Using the new NDB$EPOCH_TRANS function, the primary will overwrite the data in the secondary for the effected row(s) <strong>and</strong> any other rows that were updated in the same transaction (even if they are in tables for which conflict detection has not been enabled).</p>
<p>In fact the algorithm goes a step further and if there were subsequent transactions on the secondary that wrote to the conflicting rows then all of the changes from those dependent transactions on the secondary will be backed-out as well.</p>
<h2>Worked example</h2>
<p>In this section, we step through how to setup the active-active replication, with the new conflict detection/resolution feature enabled and then test it out by manually introducing some conflicting transations.</p>
<h3>Set-up MySQL Clusters and basic active-acative replication</h3>
<div id="attachment_2156" class="wp-caption alignright" style="width: 310px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/11/ActiveActive_ServerConfig.png"><img class="size-medium wp-image-2156" title="ActiveActive_ServerConfig" src="http://www.clusterdb.com/wp-content/uploads/2011/11/ActiveActive_ServerConfig-300x160.png" alt="Hosts used for active-active replication tests" width="300" height="160" /></a><p class="wp-caption-text">Hosts used for replication</p></div>
<p>To keep things simple, just two hosts are used; &#8220;black&#8221; will contain all nodes for the primary cluster and &#8220;blue&#8221; will contain all nodes for the secondary. As an extra simplification a single MySQL Server in each cluster will act as both the master and the slave.</p>
<p>This post will quickly show the configuration files and steps to get the 2 clusters up and running but for a better understanding of these steps you can refer to <a title="Deploying MySQL Cluster over multiple hosts" href="http://www.clusterdb.com/mysql-cluster/deploying-mysql-cluster-over-multiple-hosts/" target="_new">Deploying MySQL Cluster over multiple hosts</a>.</p>
<p>config.ini (black):</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">[ndb_mgmd]
hostname=localhost
datadir=/home/billy/my_cluster/data
nodeid=1

[ndbd default]
noofreplicas=2
datadir=/home/billy/my_cluster/data

[ndbd]
hostname=localhost
nodeid=3

[ndbd]
hostname=localhost
nodeid=4

[mysqld]
nodeid=50</pre>
<p>config.ini (blue):</p>
<pre style="padding-left: 30px; font-size: smaller; color: #339;">[ndb_mgmd]
hostname=localhost
datadir=/home/billy/my_cluster/data
nodeid=1

[ndbd default]
noofreplicas=2
datadir=/home/billy/my_cluster/data

[ndbd]
hostname=localhost
nodeid=3

[ndbd]
hostname=localhost
nodeid=4

[mysqld]
nodeid=50</pre>
<p>my.cnf for primary cluster (black):</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">[mysqld]
ndbcluster
datadir=/home/billy/my_cluster/data
server-id=8
replicate-ignore-table=mysql.ndb_replication
ndb-log-transaction-id=1
binlog-format=ROW
ndb-log-update-as-write=0</pre>
<p>my.cnf for secondary cluster (blue):</p>
<pre style="padding-left: 30px; font-size: smaller; color: #339;">[ndb_mgmd]
[mysqld]
ndbcluster
datadir=/home/billy/my_cluster/data
server-id=9
log-bin=blue-bin.log
ndb-log-transaction-id=1
binlog-format=ROW
ndb-log-update-as-write=0</pre>
<p>Note that the options set in the my.cnf file are very important &#8211; if any of these are missing then things will not work as expected.</p>
<p>Start up primary cluster (black):</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">billy@black:~/my_cluster$ ndb_mgmd --initial
   -f conf/config.ini --configdir=/home/billy/my_cluster/conf/
billy@black:~/my_cluster$ ndbd --initial
billy@black:~/my_cluster$ ndbd --initial
billy@black:~/my_cluster$ ndb_mgm -e show # wait for ndbds to finish starting
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=3    @127.0.0.1  (mysql-5.5.15 ndb-7.2.1, Nodegroup: 0, Master)
id=4    @127.0.0.1  (mysql-5.5.15 ndb-7.2.1, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @127.0.0.1  (mysql-5.5.15 ndb-7.2.1)

[mysqld(API)]   3 node(s)
id=50 (not connected, accepting connect from any host)

billy@black:~/my_cluster$ mysqld --defaults-file=conf/my.cnf &amp;</pre>
<p>Start up secondary cluster (blue):</p>
<pre style="padding-left: 30px; font-size: smaller; color: #339;">billy@blue:~/my_cluster$ ndb_mgmd --initial
   -f conf/config.ini --configdir=/home/billy/my_cluster/conf/
billy@blue:~/my_cluster$ ndbd --initial
billy@blue:~/my_cluster$ ndbd --initial
billy@blue:~/my_cluster$ ndb_mgm -e show # wait for ndbds to finish starting
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=3    @127.0.0.1  (mysql-5.5.15 ndb-7.2.1, Nodegroup: 0, Master)
id=4    @127.0.0.1  (mysql-5.5.15 ndb-7.2.1, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @127.0.0.1  (mysql-5.5.15 ndb-7.2.1)

[mysqld(API)]   3 node(s)
id=50 (not connected, accepting connect from any host)

billy@blue:~/my_cluster$ mysqld --defaults-file=conf/my.cnf &amp;</pre>
<p>Both clusters are now running and replication can be activated for both sites:</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">billy@black:~/my_cluster$ mysql -u root --prompt="black-mysql&gt; "
black-mysql&gt; CREATE USER repl_user@192.168.1.16;
black-mysql&gt; GRANT REPLICATION SLAVE ON *.* TO repl_user@192.168.1.16
                 IDENTIFIED BY 'billy';</pre>
<pre style="padding-left: 30px; font-size: smaller; color: #339;">billy@blue:~/my_cluster$ mysql -u root --prompt="blue-mysql&gt; "
blue-mysql&gt; CREATE USER repl_user@192.168.1.20;
blue-mysql&gt; GRANT REPLICATION SLAVE ON *.* TO repl_user@192.168.1.20
                 IDENTIFIED BY 'billy';
blue-mysql&gt; CHANGE MASTER TO MASTER_HOST='192.168.1.20',
    -&gt; MASTER_USER='repl_user',
    -&gt; MASTER_PASSWORD='billy',
    -&gt; MASTER_LOG_FILE='',
    -&gt; MASTER_LOG_POS=4;
blue-mysql&gt; START SLAVE;</pre>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; CHANGE MASTER TO MASTER_HOST='192.168.1.16',
    -&gt; MASTER_USER='repl_user',
    -&gt; MASTER_PASSWORD='billy',
    -&gt; MASTER_LOG_FILE='',
    -&gt; MASTER_LOG_POS=4;
black-mysql&gt; START SLAVE;</pre>
<h3>Set up enhanced conflict detection &amp; resolution</h3>
<p>The first step is to identify the tables that need conflict detection enabling. Each of those tables then has to have an entry in the mysql.ndb_replication table where they&#8217;re tagged as using the new NDB$EPOCH_TRANS() function &#8211; you could also choose to use NDB$EPOCH(), in which case only the changes to conflicting rows will be backed-out rather than the full transactions. A few things to note:</p>
<ul>
<li>This must be done <strong>before</strong> creating the application tables themselves</li>
<li>Should only be done on the primary</li>
<li>By default the table doesn&#8217;t exist and so the very first step is to create it</li>
</ul>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; CREATE TABLE mysql.ndb_replication  (
    -&gt;     db VARBINARY(63),
    -&gt;     table_name VARBINARY(63),
    -&gt;     server_id INT UNSIGNED,
    -&gt;     binlog_type INT UNSIGNED,
    -&gt;     conflict_fn VARBINARY(128),
    -&gt;     PRIMARY KEY USING HASH (db, table_name, server_id)
    -&gt; )   ENGINE=NDB
    -&gt; PARTITION BY KEY(db,table_name);
black-mysql&gt; INSERT INTO mysql.ndb_replication VALUES ('clusterdb', 'simple1', 8, 0,
'NDB$EPOCH_TRANS()');
black-mysql&gt; INSERT INTO mysql.ndb_replication VALUES ('clusterdb', 'simple2', 8, 0,
'NDB$EPOCH_TRANS()');
black-mysql&gt; INSERT INTO mysql.ndb_replication VALUES ('clusterdb', 'simple3', 8, 0,
'NDB$EPOCH_TRANS()');</pre>
<p>For each of these tables you should also create an exceptions table which will record any conflicts that have resulted in changes being rolled back; the format of these tables is rigidly defined and so take care to copy the types exactly; again this only needs doing on the primary:</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; CREATE DATABASE clusterdb;USE clusterdb;
black-mysql&gt; CREATE TABLE <strong>simple1$EX</strong> (server_id INT UNSIGNED,
               master_server_id INT UNSIGNED, master_epoch BIGINT UNSIGNED,
               count INT UNSIGNED, id INT NOT NULL, PRIMARY KEY(server_id,
               master_server_id, master_epoch, count)) ENGINE=NDB;
black-mysql&gt; CREATE TABLE <strong>simple2$EX</strong> (server_id INT UNSIGNED,
               master_server_id INT UNSIGNED, master_epoch BIGINT UNSIGNED,
               count INT UNSIGNED, id INT NOT NULL, PRIMARY KEY(server_id,
               master_server_id, master_epoch, count)) ENGINE=NDB;
black-mysql&gt; CREATE TABLE <strong>simple3$EX</strong> (server_id INT UNSIGNED,
               master_server_id INT UNSIGNED, master_epoch BIGINT UNSIGNED,
               count INT UNSIGNED, id INT NOT NULL, PRIMARY KEY(server_id,
               master_server_id, master_epoch, count)) ENGINE=NDB;</pre>
<p>Finally, the application tables themselves can be created (this only needs doing on the primary as they&#8217;ll be replicated to the secondary):</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; CREATE TABLE simple1 (id INT NOT NULL PRIMARY KEY, value INT) ENGINE=ndb;
black-mysql&gt; CREATE TABLE simple2 (id INT NOT NULL PRIMARY KEY, value INT) ENGINE=ndb;
black-mysql&gt; CREATE TABLE simple3 (id INT NOT NULL PRIMARY KEY, value INT) ENGINE=ndb;</pre>
<p>Everything is now set up and the new configuration can be tested to ensure that conflicts are detected and the correct updates are rolled back.</p>
<h3>Testing enhanced active-active replication and conflict detection</h3>
<p>The first step is to add some data to our new tables (note that at this point replication is running and so they only need to be created on the primary) and then update 1 row to make sure that it is replicated to the secondary:</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; INSERT INTO simple1 VALUES (1,10);
black-mysql&gt; INSERT INTO simple2 VALUES (1,10);
black-mysql&gt; INSERT INTO simple3 VALUES (1,10);
black-mysql&gt; UPDATE simple1 SET value=12 WHERE id=1;</pre>
<pre style="padding-left: 30px; font-size: smaller; color: #339;">blue-mysql&gt; USE clusterdb;
blue-mysql&gt; SELECT * FROM simple1;
+----+-------+
| id | value |
+----+-------+
|  1 |    12 |
+----+-------+</pre>
<p>It is important that the NDB$EPOCH_TRANS() function rolls back any transactions on the secondary that involve a conflict (as well as subsequent, dependent transactions that modify the same rows); to do this manually the simplest approach is to stop the slave IO thread on the secondary thread in order to increase the size of the window of conflict (which is otherwise very short). Once the slave IO thread has been stopped a change is made to table simple1 on the primary and then the secondary makes a (conflicting) change to the same row as well as making a change to table simple2 in the same transaction. A second transaction on the primary will change a row in simple3 &#8211; as it doesn&#8217;t touch any rows that have been involved in a conflict then that change should stand.</p>
<pre style="padding-left: 30px; font-size: smaller; color: #339;">blue-mysql&gt; STOP SLAVE IO_THREAD;</pre>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; UPDATE simple1 SET value=13 WHERE id=1;</pre>
<pre style="padding-left: 30px; font-size: smaller; color: #339;">blue-mysql&gt; BEGIN; # conflicting transaction
blue-mysql&gt; UPDATE simple1 SET value=20 WHERE id=1;
blue-mysql&gt; UPDATE simple2 SET value=20 WHERE id=1;
blue-mysql&gt; COMMIT;
blue-mysql&gt; UPDATE simple3 SET value=20 WHERE id=1; # non conflicting
blue-mysql&gt; SELECT * FROM simple1;
+----+-------+
| id | value |
+----+-------+
|  1 |    20 |
+----+-------+
blue-mysql&gt; SELECT * FROM simple2;
+----+-------+
| id | value |
+----+-------+
|  1 |    20 |
+----+-------+
blue-mysql&gt; SELECT * FROM simple3;
+----+-------+
| id | value |
+----+-------+
|  1 |    20 |
+----+-------+</pre>
<p>If you now check the exception tables then you can see that the primary (black) has received the changes from the secondary (blue) and because the first transaction updated the same row in simple1 during its window of conflict it has recorded that the change needs to be rolled back &#8211; this will happen as soon as the replication thread is restarted on the secondary:</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; SELECT * FROM simple1$EX;
+-----------+------------------+---------------+-------+----+
| server_id | master_server_id | master_epoch  | count | id |
+-----------+------------------+---------------+-------+----+
|         8 |                9 | 1494648619009 |     3 |  1 |
+-----------+------------------+---------------+-------+----+

black-mysql&gt; SELECT * FROM simple2$EX;
+-----------+------------------+---------------+-------+----+
| server_id | master_server_id | master_epoch  | count | id |
+-----------+------------------+---------------+-------+----+
|         8 |                9 | 1494648619009 |     1 |  1 |
+-----------+------------------+---------------+-------+----+

black-mysql&gt; SELECT * FROM simple3$EX;
Empty set (0.05 sec)</pre>
<pre style="padding-left: 30px; font-size: smaller; color: #339;">blue-mysql&gt; START SLAVE IO_THREAD;
blue-mysql&gt; SELECT * FROM simple1;
+----+-------+
| id | value |
+----+-------+
|  1 |    13 |
+----+-------+

blue-mysql&gt; SELECT * FROM simple2;
+----+-------+
| id | value |
+----+-------+
|  1 |    10 |
+----+-------+

blue-mysql&gt; SELECT * FROM simple3;
+----+-------+
| id | value |
+----+-------+
|  1 |    20 |
+----+-------+</pre>
<p>These are the results we expect &#8211; simple1 has the value set by the primary with the subsequent change on the secondary rolled back; simple2 was not updated by the primary but the change on the secondary was rolled back as it was made in the same transaction as the conflicting update to simple1. The change on the secondary to simple3 has survived as it was made outside of any conflicting transaction and the change was not dependent on any conflicting changes. Finally just confirm that the data is identical on the primary:</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; SELECT * FROM simple1;
+----+-------+
| id | value |
+----+-------+
|  1 |    13 |
+----+-------+

black-mysql&gt; SELECT * FROM simple2;
+----+-------+
| id | value |
+----+-------+
|  1 |    10 |
+----+-------+

black-mysql&gt; SELECT * FROM simple3;
+----+-------+
| id | value |
+----+-------+
|  1 |    20 |
+----+-------+</pre>
<p>Statistics are provided on the primary that record that 1 conflict has been detected, effecting 1 transaction and that it resulted in 2 row changes being rolled back:</p>
<pre style="padding-left: 30px; font-size: smaller; color: #000;">black-mysql&gt; SHOW STATUS LIKE 'ndb_conflict%';
+------------------------------------------+-------+
| Variable_name                            | Value |
+------------------------------------------+-------+
| Ndb_conflict_fn_max                      | 0     |
| Ndb_conflict_fn_old                      | 0     |
| Ndb_conflict_fn_max_del_win              | 0     |
| Ndb_conflict_fn_epoch                    | 0     |
| Ndb_conflict_fn_epoch_trans              | 1     |
| Ndb_conflict_trans_row_conflict_count    | 1     |
| Ndb_conflict_trans_row_reject_count      | 2     |
| Ndb_conflict_trans_reject_count          | 1     |
| Ndb_conflict_trans_detect_iter_count     | 1     |
| Ndb_conflict_trans_conflict_commit_count | 1     |
+------------------------------------------+-------+</pre>
<p>We&#8217;re anxious to get feedback on this feature and so please go ahead and <a title="Download MySQL Cluster 7.2.1" href="http://dev.mysql.com/downloads/cluster/#downloads" target="_new">download MySQL Cluster 7.2.1</a> and let us know how you get on through the comments for this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/enhanced-conflict-resolution-with-mysql-cluster-active-active-replication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Cluster 7.1.17 available</title>
		<link>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-17-available/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-cluster-7-1-17-available</link>
		<comments>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-17-available/#comments</comments>
		<pubDate>Sat, 19 Nov 2011 08:05:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.1]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2135</guid>
		<description><![CDATA[The binary version for MySQL Cluster 7.1.17 has now been made available at http://www.mysql.com/downloads/cluster/ (GPL version) or https://support.oracle.com/ (commercial version) A description of all of the changes (fixes) that have gone into MySQL Cluster 7.1.17 (compared to 7.1.15a) can be found by combining the summaries from the official MySQL Cluster documentation for Cluster &#8211; 7.1.16 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png"><img class="alignright size-full  wp-image-919" title="mysql-cluster-logo-150x105" src="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png" alt="" width="150" height="105" /></a><br />
The binary version for MySQL Cluster 7.1.17 has now been made available at <a href="http://www.mysql.com/downloads/cluster/" target="_blank">http://www.mysql.com/downloads/cluster/</a> (GPL version) or <a href="https://support.oracle.com/" target="_blank">https://support.oracle.com/</a> (commercial version)</p>
<p>A description of all of the changes (fixes) that have gone into MySQL Cluster 7.1.17 (compared to 7.1.15a) can be found by combining the summaries from the official MySQL Cluster documentation for Cluster &#8211; <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-news-5-1-56-ndb-7-1-16.html" target="_blank">7.1.16 Change log</a> &#038;  <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-news-5-1-56-ndb-7-1-17.html" target="_blank">7.1.17 Change log</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/mysql-cluster-7-1-17-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Further MySQL Cluster additions to MySQL Enterprise Monitor</title>
		<link>http://www.clusterdb.com/mysql-cluster/further-mysql-cluster-additions-to-mysql-enterprise-monitor/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=further-mysql-cluster-additions-to-mysql-enterprise-monitor</link>
		<comments>http://www.clusterdb.com/mysql-cluster/further-mysql-cluster-additions-to-mysql-enterprise-monitor/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 15:19:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.1]]></category>
		<category><![CDATA[MySQL Cluster 7.2]]></category>
		<category><![CDATA[MySQL Enterprise Monitor]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2086</guid>
		<description><![CDATA[About 11 months ago I described the MySQL Cluster functionality that was added to MySQL Enterprise Monitor 2.3; this new post is intended to just bring this up to date &#8211; briefly describing the new graph and advisors which have been added since then (up to and including MEM 2.3.7). Cluster Data Node Has Been [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_2087" class="wp-caption alignright" style="width: 310px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/10/Data_Node_Restarted_alert.jpg"><img class="size-medium wp-image-2087" title="Data_Node_Restarted_alert" src="http://www.clusterdb.com/wp-content/uploads/2011/10/Data_Node_Restarted_alert-300x285.jpg" alt="" width="300" height="285" /></a><p class="wp-caption-text">Data Node Restarted alert</p></div>
<p>About 11 months ago I described the <a href="http://www.clusterdb.com/mysql-cluster/monitoring-mysql-cluster-with-mysql-enterprise-monitor/" target="_blank">MySQL Cluster functionality that was added to MySQL Enterprise Monitor 2.3</a>; this new post is intended to just bring this up to date &#8211; briefly describing the new graph and advisors which have been added since then (up to and including MEM 2.3.7).</p>
<h3>Cluster Data Node Has Been Restarted</h3>
<p>This new alert flags when a data node has been restarted (by default it alerts on any data node that has started in the last 10 minutes but you can change that interval if you wish). If you manually perform a restart (e.g. as part of a rolling upgrade) then you can safely ignore this alert (or you may even want to temporarily unschedule it first). However if the restart was spontaneous then this can be an early warning for you to take a look at the error logs and address any issues before the situation worsens.</p>
<h3>Cluster DiskPageBuffer Hit Ratio Is Low (&amp; associated graph)</h3>
<p>The Disk Page Buffer is a cache on each data node which is used when using disk-based tables. Like any cache, the higher the hit rate the better the performance. Tuning the size of this cache can have a significant effect on your system &#8211; the new graph helps you see the results of your changes and the alert warns you when the ration falls below an acceptable level (this could happen for example temporarily after a data node restart or permanently when the active data set grows).</p>
<p>The ndbinfo database has a new table &#8220;diskpagebuffer&#8221; which contains the raw information needed to calculate the cache hit ration and it is the source of the data for the new alert and graph. If you wanted to calculate the cache hit ratio for yourself directly from this table then you can use the following query:</p>
<pre><span style="color: #003366;">mysql&gt; SELECT node_id, page_requests_direct_return AS hit, </span>
<span style="color: #003366;"> page_requests_wait_io AS miss,  100*page_requests_direct_return/</span>
<span style="color: #003366;"> (page_requests_direct_return+page_requests_wait_io) AS hit_rate
  FROM ndbinfo.diskpagebuffer;</span></pre>
<pre><span style="color: #003366;">
+---------+------+------+----------+
| node_id | hit  | miss | hit_rate |
+---------+------+------+----------+
| 3       | 6    | 3    | 66.6667  |
| 4       | 10   | 3    | 76.9231  |
+---------+------+------+----------+</span></pre>
<p>The alert is first raised (info level) when the hit rate falls bellow 97%, the warning level is raised at 90% and the critical level at 80%. Again, you can alter any of these thresholds.</p>
<p>The new graph simply displays how the hit rate varies over time so that you can spot trends.</p>
<p>As a reminder you can get more information on the <a href="http://www.clusterdb.com/mysql-cluster/monitoring-mysql-cluster-with-mysql-enterprise-monitor/" target="_blank">original set of alerts and graphs here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/further-mysql-cluster-additions-to-mysql-enterprise-monitor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Cluster Webinar on Wednesday: What&#8217;s New in MySQL Cluster 7.2.1 Development Milestone Release</title>
		<link>http://www.clusterdb.com/mysql-cluster/mysql-cluster-webinar-on-wednesday-whats-new-in-mysql-cluster-7-2-1-development-milestone-release/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-cluster-webinar-on-wednesday-whats-new-in-mysql-cluster-7-2-1-development-milestone-release</link>
		<comments>http://www.clusterdb.com/mysql-cluster/mysql-cluster-webinar-on-wednesday-whats-new-in-mysql-cluster-7-2-1-development-milestone-release/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 07:41:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.2]]></category>
		<category><![CDATA[webinar]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2078</guid>
		<description><![CDATA[There&#8217;s a webinar this Wednesday (9 am Pacific; 5 pm UK; 6 pm CET) that explains what&#8217;s new in the MySQL Cluster Development Milestone Release &#8211; register here for free access. Join this session to learn about the latest enhancements to the MySQL Cluster database, enabling even more of the latest generation of web, telecoms [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png"><img class="alignright size-full wp-image-919" title="mysql-cluster-logo-150x105" src="http://www.clusterdb.com/wp-content/uploads/2010/02/mysql-cluster-logo-150x105.png" alt="" width="150" height="105" /></a>There&#8217;s a webinar this Wednesday (9 am Pacific; 5 pm UK; 6 pm CET) that explains what&#8217;s new in the MySQL Cluster Development Milestone Release &#8211; <a href="http://www.mysql.com/news-and-events/web-seminars/display-665.html?p=EnNL" target="_blank">register here for free access</a>.</p>
<p>Join this session to learn about the latest enhancements to the MySQL Cluster database, enabling even more of the latest generation of web, telecoms and embedded applications to take advantage of high write scalability, SQL and NoSQL interfaces and 99.999% availability.</p>
<p>New capabilities include:</p>
<ul>
<li> 70x higher JOIN performance for the latest generation of web applications using Adaptive Query Localization, enabling real-time analytics across live data sets</li>
<li>New NoSQL interface via memcached to further enhance developer flexibility and productivity</li>
<li>Simplified global scalability with multi-site clusters and enhanced Active/Active replication</li>
<li>Integration with the MySQL 5.5 release, enabling users to fully exploit the latest capabilities of both the InnoDB and MySQL Cluster storage engines within a single application</li>
<li>Streamlined cluster provisioning and maintenance</li>
</ul>
<p>The 2nd Development Milestone Release of MySQL Cluster 7.2.1 was announced at <a title="MySQL Cluster material from Oracle Open World 2011" href="http://www.clusterdb.com/mysql-cluster/mysql-cluster-material-from-oracle-open-world-2011/" target="_blank">Oracle OpenWorld 2011</a>. This release is now available for <a href="http://dev.mysql.com/downloads/cluster/#downloads" target="_blank">download </a>and evaluation under the GPL license. This session will help to get you started with this latest release.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/mysql-cluster-webinar-on-wednesday-whats-new-in-mysql-cluster-7-2-1-development-milestone-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Cluster material from Oracle Open World 2011</title>
		<link>http://www.clusterdb.com/mysql-cluster/mysql-cluster-material-from-oracle-open-world-2011/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-cluster-material-from-oracle-open-world-2011</link>
		<comments>http://www.clusterdb.com/mysql-cluster/mysql-cluster-material-from-oracle-open-world-2011/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 09:54:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.2]]></category>
		<category><![CDATA[MySQL Cluster CGE]]></category>
		<category><![CDATA[oow11]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2069</guid>
		<description><![CDATA[For those people that weren&#8217;t able to attend the MySQL Cluster demo or sessions at this year&#8217;s Oracle Open World (or even for those that did) and would like copies of the material, links are provided here. Building Scalable &#38; Highly Available Database Services with MySQL Cluster &#8211; includes a description of the features in [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clusterdb.com/wp-content/uploads/2011/08/Oracle_OpenWorld_2011.jpg"><img class="alignright size-medium wp-image-1918" title="Oracle_OpenWorld_2011" src="http://www.clusterdb.com/wp-content/uploads/2011/08/Oracle_OpenWorld_2011-300x74.jpg" alt="" width="300" height="74" /></a>For those people that weren&#8217;t able to attend the MySQL Cluster demo or sessions at this year&#8217;s Oracle Open World (or even for those that did) and would like copies of the material, links are provided here.</p>
<ul>
<li><a href="http://www.clusterdb.com/oow11/OOW_MySQLCluster.pdf" target="_blank">Building Scalable &amp; Highly Available Database Services with MySQL Cluster</a> &#8211; includes a description of the features in the new MySQL Cluster7.2  Development Milestone Release 2</li>
<li><a href="http://www.clusterdb.com/oow11/NoSQL_and_MySQL_Best_of_both_worlds.pdf" target="_blank">NoSQL Access to MySQL: The Best of Both Worlds</a> &#8211; Covers what people are looking for from NoSQL data stores and how MySQL Cluster can meet these needs (both in terms of database characteristics and the APIs offered to applications)</li>
<li><a href="http://www.clusterdb.com/oow11/Getting_the_most_out_of_MySQL_on_Windows_OOW2011.pdf" target="_blank">Getting the most out of MySQL on Windows</a> &#8211; How to deliver Highly Available applications with MySQL on Windows (including replication, Windows Server Failover Clustering and MySQL Cluster) as well as the latest in MySQL tools and the Windows installer.</li>
<li><a href="http://www.clusterdb.com/oow11/MySQL_Cluster_Demo.swf" target="_blank">MySQL Cluster Demo</a> &#8211; Interactive flash demo, used in the MySQL demo area</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/mysql-cluster-material-from-oracle-open-world-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>70x Faster Joins with AQL in MySQL Cluster 7.2 DMR</title>
		<link>http://www.clusterdb.com/mysql-cluster/70x-faster-joins-with-aql-in-mysql-cluster-7-2-dmr/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=70x-faster-joins-with-aql-in-mysql-cluster-7-2-dmr</link>
		<comments>http://www.clusterdb.com/mysql-cluster/70x-faster-joins-with-aql-in-mysql-cluster-7-2-dmr/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 20:21:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[AQL]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster 7.2]]></category>

		<guid isPermaLink="false">http://www.clusterdb.com/?p=2027</guid>
		<description><![CDATA[The new MySQL Cluster Development Milestone Release just announced by Oracle includes 2 new features which when combined can improve the performance of joins by a factor of 70x (or even higher). The first enhancement is that MySQL Cluster now provides the MySQL Server with better information on the available indexes which allows the MySQL [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_2030" class="wp-caption alignright" style="width: 310px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/09/AQL_70x_faster_join.jpg"><img class="size-medium wp-image-2030" title="AQL_70x_faster_join" src="http://www.clusterdb.com/wp-content/uploads/2011/09/AQL_70x_faster_join-300x261.jpg" alt="" width="300" height="261" /></a><p class="wp-caption-text">70x faster joins with AQL</p></div>
<p>The new MySQL Cluster Development Milestone Release just announced by Oracle includes 2 new features which when combined can improve the performance of joins by a factor of 70x (or even higher). The first enhancement is that MySQL Cluster now provides the MySQL Server with better information  on the available indexes which allows the MySQL optimizer to automatically produce better query execution plans. Previously it was up to the user to provide hints to the optimizer. The second new feature is Adaptive Query Localization which allows the work of the join to be distributed across the data nodes (local to the data it&#8217;s working with) rather than up in the MySQL Server; this allows more computing power to be applied to calculating the join as well as dramatically reducing the number of messages being passed around the system. The combined result is that your joins can now run <strong>MUCH</strong> faster and this post describes a test that results in a 70x speed-up for a real-world query.</p>
<h2>The Query</h2>
<div id="attachment_2033" class="wp-caption alignright" style="width: 310px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/09/AQL_Query.jpg"><img class="size-medium wp-image-2033" title="AQL_Query" src="http://www.clusterdb.com/wp-content/uploads/2011/09/AQL_Query-300x171.jpg" alt="" width="300" height="171" /></a><p class="wp-caption-text">11-Way Join used in Test</p></div>
<p>The join used in this test is based on a real-world example used for an on-line store/Content Management System. The original query identified all of the media in the system which was appropriate to a particular device and for which a user is entitled to access. As this query is part of a customer&#8217;s application I&#8217;ve replaced all of the table and column names.</p>
<p>The join runs across 11 tables (which contain 33.5K rows in total) and produces a result set of 2,060 rows, each with 19 columns. The figure to the right illustrates the join and the full join is included below.</p>
<pre style="color: #000080;">SELECT
        tab1.uniquekey,
        tab8.name,
        tab8.tab8id,
        tab11.name,
        tab11.tab11id,
        tab11.value,
        tab10.tab10id,
        tab10.name,
        tab2.name,
        tab2.tab2id,
        tab4.value + tab5.value + tab6.value,
        tab3.colx,
        tab3.tab3id,
        tab4.tab4id,
        tab4.name,
        tab5.tab5id,
        tab5.name,
        tab6.tab6id,
        tab6.name
FROM
        tab1,tab2,tab3,tab4,tab5,tab6,tab7,tab8,tab9,tab10,tab11
WHERE
        tab7.tab2id = tab2.tab2id	AND
        tab7.tab8id = tab8.tab8id	AND
        tab9.tab2id = tab2.tab2id	AND
	tab9.tab10id = tab10.tab10id	AND
	tab10.tab11id = tab11.tab11id	AND
        tab3.tab2id = tab2.tab2id	AND
	tab3.tab4id = tab4.tab4id	AND
	tab4.tab5id = tab5.tab5id	AND
	tab4.colz =  'Y'		AND
	tab5.tab6id = tab6.tab6id	AND
	tab6.tab6id IN (6)		AND
	(tab3.tab4id IN (66, 77, 88))	AND
	tab1.tab2id = tab2.tab2id	AND
	tab1.colx = 6;</pre>
<h2>Enabling AQL</h2>
<p>First of all, make sure that you&#8217;re using the DMR2 version of MySQL Cluster (7.2.1) available from the &#8220;Development Release&#8221; tab at  <a title="dev.mysql.com/downloads/cluster" href="dev.mysql.com/downloads/cluster" target="_blank">http://dev.mysql.com/downloads/cluster/#downloads</a></p>
<p>There are then a couple of variables to check are set:</p>
<pre style="color: #000080;">mysql> show variables like '%ndb%';</pre>
<pre style="color: #000080;">....
| ndb_index_stat_cache_entries        | 32                                                                                                                                                                                                                                                  |
| ndb_index_stat_enable               | ON                                                                                                                                                                                                                                                  |
| ndb_index_stat_option               | loop_checkon=1000ms,loop_idle=1000ms,loop_busy=100ms,update_batch=1,read_batch=4,idle_batch=32,check_batch=32,check_delay=1m,delete_batch=8,clean_delay=0,error_batch=4,error_delay=1m,evict_batch=8,evict_delay=1m,cache_limit=32M,cache_lowpct=90 |
| ndb_index_stat_update_freq          | 20                                                                                                                                                                                                                                                  |
| ndb_join_pushdown                   | ON                                                                                                                                                                                                                                                  |
....</pre>
<h2>Running the Query &#038; Results</h2>
<div id="attachment_2031" class="wp-caption alignright" style="width: 199px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/09/AQL_lab.jpg"><img class="size-medium wp-image-2031" title="AQL_lab" src="http://www.clusterdb.com/wp-content/uploads/2011/09/AQL_lab-189x300.jpg" alt="" width="189" height="300" /></a><p class="wp-caption-text">Test configuration</p></div>
<p>To get the full benefit from AQL, you should run &#8220;ANALYZE TABLE;&#8221; once for each of the tables (no need to repeat for every query). This is very important and you should start doing this as a matter of course when you create or modify a table.</p>
<p>For this test, 3 machines were used:</p>
<ol>
<li>Intel Core 2 Quad Core @2.83 GHz; 8 Gbytes RAM; single, multi-threaded data node (ndbmtd)</li>
<li>Intel Core 2 Quad Core @2.83 GHz; 8 Gbytes RAM; single, multi-threaded data node (ndbmtd)</li>
<li>4 Core Fedora VM running on VirtualBox on Windows 7, single MySQL Server</li>
</ol>
<p>The query was then run and compared to MySQL CLuster 7.1.15a:</p>
<table Style="border-width: 1px;">
<tbody>
<tr>
<td>MySQL Cluster 7.1.15a</td>
<td>1 minute 27.23 secs</td>
<td></td>
</tr>
<tr>
<td>MySQL Cluster 7.2.1 (without having run ANALYZE TABLE)</td>
<td>1 minute 5.3 secs</td>
<td>1.33x Cluster 7.1</td>
</tr>
<tr>
<td>MySQL Cluster 7.2.1 (having run ANALYZE TABLE)</td>
<td>1.26 secs</td>
<td>69.23x Cluster 7.1</td>
</tr>
</tbody>
</table>
<h2>How it Works</h2>
<div id="attachment_1626" class="wp-caption alignright" style="width: 310px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/03/Nested-Loop-Join.jpg"><img class="size-medium wp-image-1626" title="Nested Loop Join" src="http://www.clusterdb.com/wp-content/uploads/2011/03/Nested-Loop-Join-300x155.jpg" alt="" width="300" height="155" /></a><p class="wp-caption-text">Classic Nested-Loop-Join</p></div>
<p>Traditionally, joins have been implemented in the MySQL Server where the query was executed. This is implemented as a nested-loop join; for every row from the first part of the join, a request has to be sent to the data nodes in order to fetch the data for the next level of the join and for every row in that level&#8230;. This method can result in a lot of network messages which slows down the query (as well as wasting resources). When turned on, Adaptive Query Localization results in the hard work being pushed down to the data nodes where the data is locally accessible. As a bonus, the work is divided amongst the pool of data nodes and so you get parallel execution.</p>
<div id="attachment_1627" class="wp-caption alignright" style="width: 310px"><a href="http://www.clusterdb.com/wp-content/uploads/2011/03/NDB-API.jpg"><img class="size-medium wp-image-1627" title="NDB API" src="http://www.clusterdb.com/wp-content/uploads/2011/03/NDB-API-300x188.jpg" alt="" width="300" height="188" /></a><p class="wp-caption-text">NDB API</p></div>
<p>I&#8217;ll leave the real deep and dirty details to others but cover the basic concepts here. All API nodes access the data nodes using the native C++ NDB API, the MySQL Server is one example of an API node (the new <a href="http://www.clusterdb.com/mysql-cluster/scalabale-persistent-ha-nosql-memcache-storage-using-mysql-cluster" target="_blank">Memcached Cluster API</a> is another). This API has been expanded to allow parameterised or linked queries where the input from one query is dependent on the previous one. To borrow an example from an excellent <a href="http://messagepassing.blogspot.com/2011/01/low-latency-distributed-parallel-joins.html" target="_blank">post by Frazer Clement</a> on the topic, the classic way to implement a join would be&#8230;</p>
<pre style="font-size: 11px;">SQL > select t1.b, t2.c from t1,t2 where t1.pk=22 and t1.b=t2.pk;
  ndbapi > read column b from t1 where pk = 22;</pre>
<pre style="font-size: 11px;">              [round trip]</pre>
<pre style="font-size: 11px;">           (b = 15)
  ndbapi > read column c from t2 where pk = 15;</pre>
<pre style="font-size: 11px;">              [round trip]</pre>
<pre style="font-size: 11px;">           (c = 30)
           [ return b = 15, c = 30 ]</pre>
<p>Using the new functionality this can be performed with a single network round trip where the second read operation is dependent on the results of the first&#8230;</p>
<pre style="font-size: 11px;">  ndbapi > read column <strong><span style="color: #800000;">@b</span></strong>:=b from t1 where pk = 22;
           read column c from t2 where pk=<span style="color: #800000;"><strong>@b</strong></span>;</pre>
<pre style="font-size: 11px;">              [round trip]</pre>
<pre style="font-size: 11px;">           (b = 15, c = 30)
           [ return b = 15, c = 30 ]</pre>
<p>You can check whether your query is fitting these rules using EXPLAIN, for example:</p>
<pre style="padding-left: 30px; font-size: 11px;"><span style="color: #008000;">mysql> set ndb_join_pushdown=on;</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">mysql> EXPLAIN SELECT COUNT(*) FROM residents,postcodes WHERE residents.postcode=postcodes.postcode AND postcodes.town="MAIDENHEAD";</span>
<span style="color: #008000;">+----+-------------+-----------+--------+---------------+---------+---------+------------------------------+--------+--------------------------------------------------------------------------+</span>
<span style="color: #008000;">| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |</span><span style="color: #008000;"> +----+-------------+-----------+--------+---------------+---------+---------+------------------------------+--------+--------------------------------------------------------------------------+</span><span style="color: #008000;"> | 1 | SIMPLE | residents | ALL | NULL | NULL | NULL | NULL | 100000 | Parent of 2 pushed join@1 |</span><span style="color: #008000;"> | 1 | SIMPLE | postcodes | eq_ref | PRIMARY | PRIMARY | 22 | clusterdb.residents.postcode | 1 | Child of 'residents' in pushed join@1; Using where with pushed condition |</span><span style="color: #008000;"> +----+-------------+-----------+--------+---------------+---------+---------+------------------------------+--------+--------------------------------------------------------------------------+</span></pre>
<pre style="padding-left: 30px; font-size: 11px;"><span style="color: #008000;">mysql> EXPLAIN EXTENDED SELECT COUNT(*) FROM residents,postcodes,towns WHERE residents.postcode=postcodes.postcode AND postcodes.town=towns.town AND towns.county="Berkshire";</span><span style="color: #008000;"> +----+-------------+-----------+--------+---------------+---------+---------+------------------------------+--------+----------+------------------------------------------------------------------------------------------------------------------------+</span><span style="color: #008000;"> | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |</span><span style="color: #008000;"> +----+-------------+-----------+--------+---------------+---------+---------+------------------------------+--------+----------+------------------------------------------------------------------------------------------------------------------------+</span><span style="color: #008000;"> | 1 | SIMPLE | residents | ALL | NULL | NULL | NULL | NULL | 100000 | 100.00 | Parent of 3 pushed join@1 |</span><span style="color: #008000;"> | 1 | SIMPLE | postcodes | eq_ref | PRIMARY | PRIMARY | 22 | clusterdb.residents.postcode | 1 | 100.00 | Child of 'residents' in pushed join@1 |</span><span style="color: #008000;"> | 1 | SIMPLE | towns | eq_ref | PRIMARY | PRIMARY | 22 | clusterdb.postcodes.town | 1 | 100.00 | Child of 'postcodes' in pushed join@1; Using where with pushed condition: (`clusterdb`.`towns`.`county` = 'Berkshire') |</span><span style="color: #008000;"> +----+-------------+-----------+--------+---------------+---------+---------+------------------------------+--------+----------+------------------------------------------------------------------------------------------------------------------------+</span></pre>
<p>Note that if you want to check for more details why your join isn&#8217;t currently being pushed down to the data node then you can use &#8220;<span style="color: #008000;">EXPLAIN EXTENDED</span>&#8221; and then &#8220;<span style="color: #008000;">SHOW WARNINGS</span>&#8221; to get more hints. Hopefully that will allow you to tweak your queries to get the best improvements.</p>
<p>PLEASE let us know your experiences and give us examples of queries that worked well and (just as importantly) those that didn&#8217;t so that we can improve the feature &#8211; just leave a comment on this Blog with your table schemas, your query and your before/after timings.</p>
<p>Find out more on the contents of the new <a href="http://dev.mysql.com/tech-resources/articles/mysql-cluster-7.2.html">MySQL Cluster 7.2 DMR in this MySQL dev-zone article</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clusterdb.com/mysql-cluster/70x-faster-joins-with-aql-in-mysql-cluster-7-2-dmr/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

