<?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>Todd&#039;s MySQL Blog</title>
	<atom:link href="http://mysqlblog.fivefarmers.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mysqlblog.fivefarmers.com</link>
	<description>Tiny tidbits of trivia from Todd</description>
	<lastBuildDate>Thu, 26 Apr 2012 14:49:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>YEAR(2) Challenge</title>
		<link>http://mysqlblog.fivefarmers.com/2012/04/25/year2-challenge/</link>
		<comments>http://mysqlblog.fivefarmers.com/2012/04/25/year2-challenge/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 00:11:48 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=157</guid>
		<description><![CDATA[You might remember this little thing called the Y2K bug.  That&#8217;s twelve years ago, but MySQL still supports a YEAR(2) data type.  A recent internal discussion made me realize there were aspects of YEAR(2) that I didn&#8217;t fully understand, and prompts me to challenge readers to come up with a truly viable use case for [...]]]></description>
			<content:encoded><![CDATA[<p>You might remember this little thing called <a title="Y2K Bug" href="http://en.wikipedia.org/wiki/Year_2000_problem">the Y2K bug</a>.  That&#8217;s twelve years ago, but MySQL still supports a YEAR(2) data type.  A recent internal discussion made me realize there were aspects of YEAR(2) that I didn&#8217;t fully understand, and prompts me to challenge readers to come up with a truly viable use case for YEAR(2) data types.</p>
<p>A primary reason for storing only the last two digits of years is to save on storage space, so perhaps YEAR(2) makes sense for big data or in situations where storage is constrained, right?  Well, no &#8211; the number of bytes used to store YEAR(2) data is the same as what is required when YEAR(4) is used:</p>
<pre>
mysql&gt; SHOW CREATE TABLE y2\G
*************************** 1. row ***************************
Table: y2
Create Table: CREATE TABLE `y2` (
`y` year(2) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)</code>

mysql&gt; SHOW CREATE TABLE y4\G
*************************** 1. row ***************************
Table: y4
Create Table: CREATE TABLE `y4` (
`y` year(4) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql&gt; SELECT COUNT(*) FROM y2;
+----------+
| COUNT(*) |
+----------+
| 33554432 |
+----------+
1 row in set (0.00 sec)

mysql&gt; SELECT COUNT(*) FROM y4;
+----------+
| COUNT(*) |
+----------+
| 33554432 |
+----------+
1 row in set (0.00 sec)

D:\mysql-5.5.20-win32\data\test&gt;dir *.MYD
Volume in drive D is Data
Volume Serial Number is 4015-B2FF

Directory of D:\mysql-5.5.20-win32\data\test

04/25/2012  10:43 AM       234,881,024 y2.MYD
04/25/2012  10:45 AM       234,881,024 y4.MYD
</pre>
<p>Huh.</p>
<p>Well, that doesn&#8217;t make much sense, since YEAR(2) only stores the last two digits, while YEAR(4) stores all four &#8211; right?  Nope, YEAR(2) stores the full four digits, and has the same range of values as YEAR(4):</p>
<pre>
mysql&gt; TRUNCATE y2;
Query OK, 0 rows affected (0.09 sec)</code>

mysql&gt; TRUNCATE y4;
Query OK, 0 rows affected (0.05 sec)

mysql&gt; INSERT INTO y4 VALUES (1901), (2000), (2155);
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql&gt; SELECT * FROM y4 ORDER BY y;
+------+
| y    |
+------+
| 1901 |
| 2000 |
| 2155 |
+------+
3 rows in set (0.00 sec)

mysql&gt; INSERT INTO y2 SELECT * FROM y4;
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql&gt; SELECT * FROM y2 ORDER BY y;
+------+
| y    |
+------+
|   01 |
|   00 |
|   55 |
+------+
3 rows in set (0.00 sec)

mysql&gt; ALTER TABLE y2 MODIFY COLUMN y YEAR(4);
Query OK, 0 rows affected (0.13 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&gt; SELECT * FROM y2 ORDER BY y;
+------+
| y    |
+------+
| 1901 |
| 2000 |
| 2155 |
+------+
3 rows in set (0.00 sec)
</pre>
<p>OK, so maybe one would use YEAR(2) because they really, really like the fun behavior that assumes that values 70-99 are 1970-1999, and values 01-69 are years 2001-2069:</p>
<pre>
mysql&gt; TRUNCATE TABLE y2;
Query OK, 0 rows affected (0.02 sec)</code>

mysql&gt; ALTER TABLE y2 MODIFY COLUMN y YEAR(2);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&gt; INSERT INTO y2 VALUES (69), (70);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql&gt; SELECT * FROM y2 ORDER BY y;
+------+
| y    |
+------+
|   70 |
|   69 |
+------+
2 rows in set (0.00 sec)

mysql&gt; ALTER TABLE y2 MODIFY COLUMN y YEAR(4);
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&gt; SELECT * FROM y2 ORDER BY y;
+------+
| y    |
+------+
| 1970 |
| 2069 |
+------+
2 rows in set (0.00 sec)
</pre>
<p>Except that behavior is identical to YEAR(4):</p>
<pre>
mysql&gt; TRUNCATE TABLE y4;
Query OK, 0 rows affected (0.02 sec)</code>

mysql&gt; INSERT INTO y4 VALUES (69), (70);
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql&gt; SELECT * FROM y4 ORDER BY y;
+------+
| y    |
+------+
| 1970 |
| 2069 |
+------+
2 rows in set (0.00 sec)
</pre>
<p>There&#8217;s one area where behavior is different, and that&#8217;s in handling of the numeric value zero:</p>
<p>&nbsp;</p>
<pre>
mysql&gt; TRUNCATE TABLE y4;
Query OK, 0 rows affected (0.01 sec)</code>

mysql&gt; INSERT INTO y4 VALUES (0);
Query OK, 1 row affected (0.00 sec)

mysql&gt; SELECT * FROM y4;
+------+
| y    |
+------+
| 0000 |
+------+
1 row in set (0.00 sec)

mysql&gt; TRUNCATE TABLE y2;
Query OK, 0 rows affected (0.00 sec)

mysql&gt; INSERT INTO y2 VALUES (0);
Query OK, 1 row affected (0.01 sec)

mysql&gt; SELECT * FROM y2;
+------+
| y    |
+------+
|   00 |
+------+
1 row in set (0.00 sec)
</pre>
<p>Looks the same so far, right?  Under the hood, though, it&#8217;s not:</p>
<pre>
mysql&gt; ALTER TABLE y2 MODIFY COLUMN y YEAR(4);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0</code>

mysql&gt; SELECT * FROM y2;
+------+
| y    |
+------+
| 2000 |
+------+
1 row in set (0.00 sec)
</pre>
<p>So a numeric zero inserted into a YEAR(2) column will be effectively stored as 2000, while the same value inserted into a YEAR(4) will be stored as &#8220;0000&#8243; (invalid).  So, there&#8217;s one use case: When your application has to insert numeric zero values and have them stored as the year 2000.  Probably not terribly compelling.</p>
<p>Here&#8217;s one more not-so-compelling use case:  You really, really care about the number of bytes sent over the network, and only need the last two digits of a year.  As can be seen here, the number of bytes sent is lower for YEAR(2) data than YEAR(4) data &#8211; two bytes per row:</p>
<p>&nbsp;</p>
<pre>
mysql&gt; flush status;
Query OK, 0 rows affected (0.00 sec)

mysql&gt; select * from y2 limit 1;
+------+
| y    |
+------+
|   12 |
+------+
1 row in set (0.00 sec)

mysql&gt; show session status like 'bytes_sent';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Bytes_sent    | 77    |
+---------------+-------+
1 row in set (0.00 sec)</code>

mysql&gt; flush status;
Query OK, 0 rows affected (0.00 sec)

mysql&gt; select * from y4 limit 1;
+------+
| y    |
+------+
| 2012 |
+------+
1 row in set (0.00 sec)

mysql&gt; show session status like 'bytes_sent';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Bytes_sent    | 79    |
+---------------+-------+
1 row in set (0.00 sec)
</pre>
<p>But wait, if you can save bytes there, can you save bytes in other locations, like temporary tables created for sorting?  Nope &#8211; the full data is represented in the sort, otherwise this wouldn&#8217;t sort correctly:</p>
<pre>
mysql&gt; INSERT INTO y2 VALUES (1969), (1970), (2000), (2071);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0</code>

mysql&gt; SELECT * FROM y2 ORDER BY y;
+------+
| y    |
+------+
|   69 |
|   70 |
|   00 |
|   71 |
+------+
4 rows in set (0.00 sec)
</pre>
<p>There is some funky behavior related to equality matches, though:</p>
<pre>
mysql&gt; SELECT y2.y y2, y4.y y4 FROM y2 LEFT JOIN y4 ON (y2.y = y4.y);
+------+------+
| y2   | y4   |
+------+------+
|   69 | NULL |
|   70 | 1970 |
|   00 | 2000 |
|   71 | NULL |
+------+------+
4 rows in set (0.00 sec)

mysql&gt; SELECT * FROM y2 WHERE y = 1969 OR y = 2071;
+------+
| y    |
+------+
|   69 |
|   71 |
+------+
2 rows in set (0.00 sec)

mysql&gt; ALTER TABLE y2 MODIFY COLUMN y YEAR(4);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&gt; SELECT y2.y y2, y4.y y4 FROM y2 LEFT JOIN y4 ON (y2.y = y4.y);
+------+------+
| y2   | y4   |
+------+------+
| 1969 | 1969 |
| 1970 | 1970 |
| 2000 | 2000 |
| 2071 | 2071 |
+------+------+
4 rows in set (0.00 sec)
</pre>
<p>Pretty strange, no?  I actually suspect this may be a bug and will report it as such.</p>
<p>So YEAR(2) really does have the same underlying data storage requirements as YEAR(4), and there&#8217;s no internal optimization for sorting or anything like that &#8211; in fact, the only areas where there might be optimization seem to produce bad results, as shown in the last example.  There&#8217;s extremely limited savings in terms of network overhead, and special handling of numeric zeros.  Since the MySQL server sends the results over the wire with just the last two years, that would be moderately helpful if that&#8217;s how your application needs to consume the data &#8211; but it also causes the following behavior, which is an absolute deal-breaker for me.  First, here&#8217;s the original table creation and data:</p>
<pre>
mysql&gt; CREATE TABLE yd (y2 YEAR(2), y4 YEAR(4));
Query OK, 0 rows affected (0.03 sec)</code>

mysql&gt; INSERT INTO yd (y2) VALUES (1969), (1970), (2000), (2071);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql&gt; UPDATE yd SET y4 = y2;
Query OK, 4 rows affected (0.01 sec)
Rows matched: 4  Changed: 4  Warnings: 0

mysql&gt; SELECT * FROM yd ORDER BY y2;
+------+------+
| y2   | y4   |
+------+------+
|   69 | 1969 |
|   70 | 1970 |
|   00 | 2000 |
|   71 | 2071 |
+------+------+
4 rows in set (0.00 sec)
</pre>
<p>Guess what happens when you recreate this from mysqldump?</p>
<pre>
D:\&gt;mysql-5.5.20-win32\bin\mysqldump -uroot -P3307 --add-drop-table test yd | mysql-5.1.38-win32\bin\mysql -uroot -P3307 test</code>

D:\&gt;mysql-5.5.20-win32\bin\mysql -uroot -P3307 test -e"SELECT * FROM yd ORDER BY y2;"
+------+------+
| y2   | y4   |
+------+------+
|   70 | 1970 |
|   71 | 2071 |
|   00 | 2000 |
|   69 | 1969 |
+------+------+
</pre>
<p>Ouch.  That&#8217;s right, mysqldump produces 2-digit output, which &#8211; when replayed as an INSERT &#8211; prefixes the year with the centuries as described in the manual <a href="http://dev.mysql.com/doc/refman/5.5/en/year.html">here</a>.  The following demonstrates what&#8217;s really stored in the YEAR(2) columns after restoring using mysqldump:</p>
<pre>
mysql&gt; UPDATE yd SET y4 = y2;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 4  Changed: 2  Warnings: 0</code>

mysql&gt; SELECT * FROM yd ORDER BY y2;
+------+------+
| y2   | y4   |
+------+------+
|   70 | 1970 |
|   71 | 1971 |
|   00 | 2000 |
|   69 | 2069 |
+------+------+
4 rows in set (0.00 sec)
</pre>
<p>Nasty stuff, and reason enough for me to never touch YEAR(2).</p>
<p>Knowing the above, my challenge for you as a reader is to identify any compelling use case for YEAR(2).  Please feel free to offer suggestions as comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2012/04/25/year2-challenge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connector/J now supports authentication plugins</title>
		<link>http://mysqlblog.fivefarmers.com/2012/04/05/connectorj-now-supports-authentication-plugins/</link>
		<comments>http://mysqlblog.fivefarmers.com/2012/04/05/connectorj-now-supports-authentication-plugins/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 23:27:22 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Connector/J]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=152</guid>
		<description><![CDATA[Many people are aware that MySQL 5.5 added support for external authentication plugins, and that Oracle provides several commercial-licensed plugins that can help users leverage this functionality out-of-the-box (you can try these and other features of MySQL commercial offerings for free).  Until the recent release of Connector/J 5.1.19, though, JDBC users could not leverage the [...]]]></description>
			<content:encoded><![CDATA[<p>Many people are aware that MySQL 5.5 added support for <a href="http://dev.mysql.com/doc/refman/5.5/en/pluggable-authentication.html" target="_blank">external authentication plugins</a>, and that<a href="http://mysql.com/products/enterprise/security.html" target="_blank"> Oracle provides several commercial-licensed plugins</a> that can help users leverage this functionality out-of-the-box (you can<a href="http://mysql.com/trials/" target="_blank"> try these and other features </a>of MySQL commercial offerings for free).  Until the <a href="https://dev.mysql.com/doc/refman/5.1/en/cj-news-5-1-19.html" target="_blank">recent release of Connector/J 5.1.19</a>, though, JDBC users could not leverage the plugin capabilities of MySQL 5.5.  Now, Java users can write their own client-side plugins in support of the standard MySQL 5.5 external authentication plugins, or even server-side external authentication plugins they write themselves.</p>
<p>This release (and this feature, specifically) is also significant in at least one other way:  It&#8217;s the first release (and feature) of Connector/J authored by Alexander Soklakov &#8211; the newest member of the Connectors team and crack Java developer.  Like most things at MySQL, there was a good team backing Alex up (with Mark Matthews helping define the architecture, Rafal Somla coordinating the protocol-level changes, and Tonci Grgin overseeing it all).  Way to go, Alex and team!</p>
<p>Because the key MySQL 5.5 external authentication plugins are platform dependent (PAM, Windows), they may not be the best fit for Java users, where platform independence (and lack of reliance on native code) is a big priority.  We&#8217;re always interested to receive feature requests, though, so if you have an idea for how you would want to use MySQL external authentication in the context of your Java application, please let us know (comment here, or register the request at bugs.mysql.com).</p>
<p>The original purpose for writing this blog entry, however, was to <a href="http://mysqlblog.fivefarmers.com/2012/02/24/connectorj-extension-points-load-balancing-strategies/" target="_blank">supplement</a> my <a href="http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%e2%80%93-exception-interceptors/" target="_blank">previous entries</a> on <a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/" target="_blank">other</a> Connector/J <a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/" target="_blank">extension points</a>.  Much to my chagrin, but your benefit, Alexander was way ahead of me.  The public docs haven&#8217;t quite caught up, but there&#8217;s great content in the CHANGES file.  He even includes example and test implementations.  I&#8217;ll just quote the CHANGES file directly:</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<pre>  - Added support for pluggable authentication via the com.mysql.jdbc.AuthenticationPlugin
    interface (which extends standard "extension" interface). Examples are in
    com/mysql/jdbc/authentication and in testsuite.regression.ConnectionRegressionTest.
    This introduces three new properties:

       authenticationPlugins defines comma-delimited list of classes that implement
       com.mysql.jdbc.AuthenticationPlugin and which will be used for authentication
       unless disabled by "disabledAuthenticationPlugins" property.

       disabledAuthenticationPlugins defines comma-delimited list of classes implementing
       com.mysql.jdbc.AuthenticationPlugin or mechanisms, i.e. "mysql_native_password".
       The authentication plugins or mechanisms listed will not be used for authentication
       which will fail if it requires one of them. It is an error to disable the default
       authentication plugin (either the one named by "defaultAuthenticationPlugin" property
       or the hard-coded one if "defaultAuthenticationPlugin" propery is not set).

       defaultAuthenticationPlugin defines name of a class implementing
       com.mysql.jdbc.AuthenticationPlugin which will be used as the default authentication
       plugin. It is an error to use a class which is not listed in "authenticationPlugins"
       nor it is one of the built-in plugins. It is an error to set as default a plugin
       which was disabled with "disabledAuthenticationPlugins" property. It is an error
       to set this value to null or the empty string (i.e. there must be at least a valid
       default authentication plugin specified for the connection, meeting all constraints
       listed above).</pre>
<p>It&#8217;s great work from Alexander, and I&#8217;m looking forward to his future work.  It also demonstrates the value of having a support organization with direct involvement in the development of all MySQL products, as this functionality was implemented in direct response to customer need.</p>
<p>Let us know if you have any problems implementing external authentication plugins, or have ideas on plugins you would find valuable for managing your Java deployments.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2012/04/05/connectorj-now-supports-authentication-plugins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Cluster Quick Start Script</title>
		<link>http://mysqlblog.fivefarmers.com/2012/03/16/mysql-cluster-quick-start-script/</link>
		<comments>http://mysqlblog.fivefarmers.com/2012/03/16/mysql-cluster-quick-start-script/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 23:49:02 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Cluster]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=146</guid>
		<description><![CDATA[Many Windows users first looking to experiment with MySQL Cluster may find the process of getting everything up and running daunting.  Fortunately, there&#8217;s MySQL Cluster Manager (MCM) which can help jump-start that process &#8211; and that&#8217;s all many people will need. In my work, I frequently have to install specific version of MySQL Server or [...]]]></description>
			<content:encoded><![CDATA[<p>Many Windows users first looking to experiment with <a href="http://www.mysql.com/products/cluster/" target="_blank">MySQL Cluster</a> may find the process of getting everything up and running daunting.  Fortunately, there&#8217;s <a href="http://dev.mysql.com/doc/mysql-cluster-manager/1.1/en/index.html" target="_blank">MySQL Cluster Manager</a> (MCM) which can help jump-start that process &#8211; and that&#8217;s all many people will need.</p>
<p>In my work, I frequently have to install specific version of MySQL Server or Cluster to validate behavior of a handful of commands, and MCM is a bit overkill.  I have a couple of tricks that I use to quickly set up MySQL Cluster on Windows environments:</p>
<ol>
<li>I always use the .ZIP packages</li>
<li>I have a set cluster data directory (in my case, D:\cluster-data)</li>
<li>I have a standard Cluster configuration file (config.ini) that I use, with two data nodes, one management node, and two SQL nodes</li>
<li>I have a script I use to do some setup and start the necessary processes, after first making sure no other Cluster is running and there are no port conflicts for MySQL SQL nodes</li>
</ol>
<p>The Cluster configuration file is very sparse:</p>
<p>&nbsp;</p>
<pre>[ndbd default]
NoOfReplicas=2
DataDir=D:\cluster-data

[NDB_MGMD]
HostName=127.0.0.1
NodeId=1
DataDir= D:\cluster-data
# Data Nodes
# One entry for each node
[NDBD]
HostName=127.0.0.1
NodeId=2
[NDBD]
HostName=127.0.0.1
NodeId=3
# SQL Nodes
# One entry for each node
[MYSQLD]
HostName=127.0.0.1
[MYSQLD]</pre>
<p>If you use this configuration file, make sure that you also create the DataDir you specify &#8211; the Cluster management node will not start if it does not exist.</p>
<p>The batch file I use is similarly simple, but it saves me plenty of time when I have to quickly deploy a specific version for a quick 5-minute test:</p>
<pre>REM stop MySQL SQL nodes running on ports 3307 or 3308, if any exist
REM (ignore errors if mysqld isn't available on the port)
bin\mysqladmin -uroot -P3307 shutdown
bin\mysqladmin -uroot -P3308 shutdown

REM stop MySQL data and management nodes, if running (connection failure errors can be ignored)
bin\ndb_mgm -e "shutdown"

REM start the MySQL Cluster management node
start bin\ndb_mgmd --configdir=%CD% -f config.ini

REM start the MySQL Cluster data nodes, passing --initial if the batch file received that argument
start bin\ndbd %1
start bin\ndbd %1

REM created a copy of the MySQL SQL node data directory, if it doesn't already exist
IF NOT EXIST %CD%\data2 XCOPY %CD%\data %CD%\data2 /i /S

REM start the MySQL SQL nodes on ports 3307 and 3308
start bin\mysqld --no-defaults --basedir=%CD% --datadir=%CD%\data --port=3307 --ndbcluster --ndb-connectstring=localhost:1186 --console
start bin\mysqld --no-defaults --basedir=%CD% --datadir=%CD%\data2 --port=3308 --ndbcluster --ndb-connectstring=localhost:1186 --console
</pre>
<p>The script expects to be run from within the directory created when unpacking the .ZIP file.  It leverages the default (blank) password for the root account in Windows .ZIP distributions to shutdown the SQL nodes, and uses port 3307 and 3308 to avoid causing problems with any existing MySQL server that may be running on port 3306 (which is my personal, persistent installation).</p>
<p>Hopefully this will help people looking to do a quick deployment of MySQL Cluster on Windows.</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2012/03/16/mysql-cluster-quick-start-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connector/J extension points &#8211; Load Balancing Strategies</title>
		<link>http://mysqlblog.fivefarmers.com/2012/02/24/connectorj-extension-points-load-balancing-strategies/</link>
		<comments>http://mysqlblog.fivefarmers.com/2012/02/24/connectorj-extension-points-load-balancing-strategies/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 23:08:05 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Connector/J]]></category>
		<category><![CDATA[JavaOne]]></category>
		<category><![CDATA[Load-balancing]]></category>
		<category><![CDATA[MySQL Cluster]]></category>
		<category><![CDATA[SVCC]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=143</guid>
		<description><![CDATA[A fourth and final Connector/J extension point I covered in my JavaOne and Silicon Valley Code Camp presentations is load-balancing strategies.  This exists in order to allow you to define behavior for balancing load across multiple back-end MySQL server instances.  MySQL Connector/J&#8217;s load-balancing implementation is a simple internal connection pool.  What appears to your application [...]]]></description>
			<content:encoded><![CDATA[<p>A fourth and final Connector/J extension point I covered in <a title="Presentation materials" href="../2011/10/09/connectorj-presentation-at-javaone-and-svcc/" target="_blank">my JavaOne and Silicon Valley Code Camp presentations</a> is load-balancing strategies.  This exists in order to allow you to define behavior for balancing load across multiple back-end MySQL server instances.  MySQL Connector/J&#8217;s load-balancing implementation is a simple internal connection pool.  What appears to your application as a single Connection object can actually have multiple physical connections to MySQL servers underneath (one per configured host/port pair).  At <a href="http://mysqlblog.fivefarmers.com/2010/07/07/connectorjs-load-balancing-failover-policies/" target="_blank">specific points</a>, Connector/J will re-balance and choose another host to interface with.  This extension point allows you to define how Connector/J determines which host it should pick next.</p>
<p>Unlike the previous extension points, my <a title="Demo code" href="../wp-content/uploads/mysqlblog.fivefarmers.com/2011/10/demo.zip" target="_blank">demo code</a> does not contain examples of this.  In this case, though, there are some standard implementations provided with Connector/J that we can look at, instead.  The two implementations shipped with Connector/J today implement a &#8220;best response time&#8221; strategy and a &#8220;random&#8221; strategy.  The default behavior when using load-balanced deployments is &#8220;random&#8221;, and the <a href="http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html" target="_blank">Connector/J configuration properties documentation</a> describes their use cases.  Below are the actual classes which define the behavior:</p>
<ul>
<li>com.mysql.jdbc.RandomBalanceStrategy</li>
<li>com.mysql.jdbc.BestResponseTimeBalanceStrategy</li>
</ul>
<p>These classes &#8211; and any user-implemented load-balancing strategy &#8211; implements the com.mysql.jdbc.BalanceStrategy interface.  As the purpose of this extension point is to define how load is balanced across MySQL instances, there&#8217;s really only one key method you need to focus on:  pickConnection().  The purpose of this method is to return a Connection (more specifically, a com.mysql.jdbc.ConnectionImpl object).  Looking at the RandomLoadBalacneStrategy code, you will see the logic that&#8217;s involved.</p>
<p>The first parameter to pickConnection() is a LoadBalancingConnectionProxy object.  This is the object that does much of the load-balancing work.  It also contains a few callback methods you will want to consider:</p>
<ol>
<li>getGlobalBlacklist() &#8211; this method returns a Map&lt;String, Long&gt; of hosts that have been identified as unavailable.  The String key is the host/port, while the Long is the time that the blacklist entry should expire.  Inside the proxy, this global blacklist is defined as a static Map, meaning that Host X will be found in the blacklist by one Connection if another Connection object put it there after experiencing problems.  Access to the static variable is synchronized, and the Map returned from this method is a local copy.</li>
<li>shouldExceptionTriggerFailover() &#8211; this method takes a SQLException and determines whether such an Exception should trigger a failover.  This, too, is user-configurable, although the defaults are usually sufficient for most deployments.  A <a href="http://mysqlblog.fivefarmers.com/2010/07/07/connectorjs-load-balancing-failover-policies/" target="_blank">previous post</a> contains detailed information on how to customize this behavior.</li>
<li>addToGlobalBlacklist() &#8211; this is the method you want to call if you want to add a host to the global blacklist.</li>
<li>createConnectionForHost() &#8211; this is a utility method that handles creation of a new ConnectionImpl object based on the host/port String, so that you don&#8217;t have to wire up ConnectionImpl objects directly.  If you look at the method implementation, you will see the work that goes into setting up a properly-configured ConnectionImpl.</li>
</ol>
<p>The remaining parameters are, in order:</p>
<ul>
<li>List&lt;String&gt; &#8211; a list of configured hosts involved in load-balancing</li>
<li>Map&lt;String, ConnectionImpl&gt; &#8211; a Map of &#8220;live&#8221; connections already established, accessed through the host/port key.  Thinking of this as a connection pool, these are the cached connections which can be reused if the host/port pair is chosen, instead of doing the additional work of setting up a new physical connection.</li>
<li>long[] &#8211; an array of response times in the same order as the List&lt;String&gt; of configured hosts.  This is used in BestResponseTimeBalanceStrategy.</li>
<li>int &#8211; number of retries that should be attempted before giving up on finding a new connection.</li>
</ul>
<p>So, what can you do with this?  People frequently ask for a true round-robin load-balancer.  Our experience has been that RandomBalanceStrategy is far better, but if you really need a true round-robin load-balancing algorithm, you could implement it here.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2012/02/24/connectorj-extension-points-load-balancing-strategies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connector/J extension points – exception interceptors</title>
		<link>http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%e2%80%93-exception-interceptors/</link>
		<comments>http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%e2%80%93-exception-interceptors/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 00:30:18 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Connector/J]]></category>
		<category><![CDATA[JavaOne]]></category>
		<category><![CDATA[SVCC]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=132</guid>
		<description><![CDATA[A third built-in extension point for MySQL Connector/J is the ExceptionInterceptor interface.  This is the third extension point covered in my recent JavaOne and Silicon Valley Code Camp presentations, and is very useful for diagnosing specific Exceptions encountered without modifying application-side code. This corresponds to slide #60 in my slide deck, and there are two [...]]]></description>
			<content:encoded><![CDATA[<p>A third built-in extension point for MySQL Connector/J is the ExceptionInterceptor interface.  This is the third extension point covered in <a title="Presentation materials" href="http://mysqlblog.fivefarmers.com/2011/10/09/connectorj-presentation-at-javaone-and-svcc/" target="_blank">my recent JavaOne and Silicon Valley Code Camp presentations</a>, and is very useful for diagnosing specific Exceptions encountered without modifying application-side code. This corresponds to slide #60 in my <a title="Slides" href="http://mysqlblog.fivefarmers.com/wp-content/uploads/mysqlblog.fivefarmers.com/2011/10/2011-ConnectorJ-Presentation.pdf" target="_blank">slide deck</a>, and there are two Java files we&#8217;ll reference from my <a title="Demo code" href="http://mysqlblog.fivefarmers.com/wp-content/uploads/mysqlblog.fivefarmers.com/2011/10/demo.zip" target="_blank">demo code</a>:</p>
<ul>
<li>demo.connectorj.ExceptionInterceptorExample</li>
<li>demo.connectork.plugins.ExampleExceptionInterceptor</li>
</ul>
<p>To implement an exception interceptor, you need to do the following:</p>
<ol>
<li>Create a Java class which implements com.mysql.jdbc.ExceptionInterceptor</li>
<li>Configure Connector/J to use your exception interceptor by passing the fully-qualified class name as the value for the &#8220;exceptionInterceptors&#8221; property.</li>
</ol>
<p>Like <a title="Statement interceptors" href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/" target="_blank">statement interceptors</a>, this extension point is stackable &#8211; you can create multiple exception interceptors, passing them in as a comma-delimited list of fully-qualified class names.  The exception interceptors are executed in order in which they are defined in the connection property.</p>
<p>The demo here simply demonstrates how this work, but doesn&#8217;t give much of an idea of the power behind this interface.  The demo code executes a command that&#8217;s not valid SQL syntax &#8211; which will trigger a server-side error &#8211; catches the normal exception, wraps it with some additional text in the message before returning it to the application (where it is hopefully logged).  So what can you do with this?</p>
<p>There are certain errors where diagnosis requires additional information about either connection or server state &#8211; at the time the exception is raised.  This gives you a hook to enable collection of this data.  For example, certain NDB (Cluster) errors map to the same MySQL Server error code and message, and you can get more information from the NDB problems by issuing SHOW WARNINGS immediately after the error.  Unless you want to recode your application, there&#8217;s a lot of value in the ability to add an ExceptionInterceptor which looks for such errors, executes the SHOW WARNINGS, takes the details returned and shoves them into the Exception message text.</p>
<p>Another example might be when you get a server error that indicates the connection character set is set to something other what it <em>should</em> be set to, based on the configuration settings, and you want to know what session character set or collation is in use.  Unless you change your application code, you can only assume what it <em>should</em> be &#8211; unless you implement an ExceptionInterceptor that collects that data when the problem is encountered and logs that information for you.</p>
<p>Generally speaking, this is an extension point that you probably won&#8217;t leverage for normal operations, but can be very useful for diagnosing Exceptions that are difficult to reproduce outside the context of your Java application deployment.  Because ExceptionInterceptors are only called when handling a SQLException thrown from Connector/J code, you don&#8217;t have to worry too much about performance penalties in production deployments.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%e2%80%93-exception-interceptors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connector/J extension points &#8211; statement interceptors</title>
		<link>http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/</link>
		<comments>http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 05:57:01 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Connector/J]]></category>
		<category><![CDATA[JavaOne]]></category>
		<category><![CDATA[SVCC]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=122</guid>
		<description><![CDATA[Continuing the review of MySQL Connector/J&#8217;s built-in extension points from my recent JavaOne and Silicon Valley Code Camp presentations, this blog posting will focus on the StatementInterceptor extension point.  As the name suggests, this allows you to hook into statement execution and alter behavior &#8211; without changing application-side code.  This corresponds to slide #59 in [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing the review of MySQL Connector/J&#8217;s built-in extension points from <a title="Presentation materials" href="http://mysqlblog.fivefarmers.com/2011/10/09/connectorj-presentation-at-javaone-and-svcc/" target="_blank">my recent JavaOne and Silicon Valley Code Camp presentations</a>, this blog posting will focus on the StatementInterceptor extension point.  As the name suggests, this allows you to hook into statement execution and alter behavior &#8211; without changing application-side code.  This corresponds to slide #59 in my <a title="Slides" href="http://mysqlblog.fivefarmers.com/wp-content/uploads/mysqlblog.fivefarmers.com/2011/10/2011-ConnectorJ-Presentation.pdf" target="_blank">slide deck</a>, and there are two Java files we&#8217;ll reference:</p>
<ul>
<li>demo.connectorj.StatementInterceptorExample</li>
<li>demo.connectork.plugins.ExampleStatementInterceptor</li>
</ul>
<p>To implement a statement interceptor, you need to do the following:</p>
<ol>
<li>Create a Java class which implements com.mysql.jdbc.StatementInterceptorV2</li>
<li>Configure Connector/J to use your statement interceptor by passing the fully-qualified class name as the value for the &#8220;statementInterceptors&#8221; property.</li>
</ol>
<p>This extension point is stackable &#8211; you can create multiple statement interceptors, passing them in as a comma-delimited list of fully-qualified class names.</p>
<p>The example provided in the demo code is pretty bland, but illustrates what can be done.  In the demo code, we&#8217;ve implemented the preProcess() method to check for a certain trigger (&#8220;/* test */&#8221; in this case), which triggers entirely different behavior than what would normally transpire.  This code simply returns the result of  &#8220;SELECT NOW()&#8221; when triggered, instead of whatever would normally be executed on the server.  You&#8217;ll probably never need this particularly functionality, but there&#8217;s other interesting stuff you could do:</p>
<ul>
<li>Add memcached without changing a line of application code, by checking memcached before executing a query, and caching the results after retrieving non-cached data from MySQL.</li>
<li>Work around MySQL server problem areas without changing application code.  Maybe you have slow-performing subqueries in an application you cannot change?  Use statement interceptors to rewrite them to more better-performing JOIN syntax equivalents.</li>
<li>Perform some standard result set transformation by wrapping ResultSetInternalMethods returned object.</li>
<li>Add fine-grained conditional audit logging or access control without changing application code.</li>
<li>Track down problematic statements that you suspect may be issued by the application, but not logged anywhere else.</li>
<li>Shard your data, and use statement interceptors to route statements to appropriate MySQL instances (or combine results fetched from multiple MySQL servers)  &#8211; again without changing application code.</li>
<li>Implement <a title="Ping tutorial" href="http://mysqlblog.fivefarmers.com/2010/08/25/connector-j-ping/">low-overhead &#8220;ping&#8221; operation</a> for connection pools that don&#8217;t allow you to define your own validation query.</li>
</ul>
<p>There&#8217;s a lot that can be done with statement interceptors, and they are very easy to wire up &#8211; there&#8217;s really only five methods you need to implement:</p>
<ul>
<li>init()  &#8211; You can set up state variables here, if needed.  Returns void, so leaving this empty is fine.</li>
<li>preProcess() &#8211; This is where you return a ResultSetInternalMethods object if you want to bypass the normal operation of the statement.  This is called before the statement is sent to the server, so you can change what is sent &#8211; or even bypass the sending &#8211; here.  If you return null, the driver executes the statement as it normally would.  If you return a non-null object, further execution is bypassed.  Note that the SQL String argument will be null for PreparedStatement objects; you&#8217;ll need to handle Statement and PreparedStatement executions differently in order to examine the SQL being sent.</li>
<li>postProcess() &#8211; Like preProcess(), but invoked by the driver after the server has returned a result set.  This allows you to change the results returned or wrap them with some sort of custom decorator.</li>
<li>executeTopLevelOnly() &#8211; Return true if you are issuing queries inside preProcess() or postProcess() that could cause infinite recursion.</li>
<li>destroy() &#8211; Clean up any local references you created in init() here.</li>
</ul>
<p>The demo code provided will give you a simple example of how to implement statement interceptors, but what you do with them is really limited only by your imagination.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Connector/J extension points &#8211; lifecycle interceptors</title>
		<link>http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/</link>
		<comments>http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 19:36:02 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Connector/J]]></category>
		<category><![CDATA[JavaOne]]></category>
		<category><![CDATA[SVCC]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=117</guid>
		<description><![CDATA[This is the first of a handful of posts to augment the presentations I gave at Java One and Silicon Valley Code Camp earlier this month.  It seems I significantly overestimated how much content I could effectively deliver in the time allotted, and left a few of my major points untouched.  These blog posts will [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first of a handful of posts to augment the <a title="Presentation slides" href="http://mysqlblog.fivefarmers.com/wp-content/uploads/mysqlblog.fivefarmers.com/2011/10/2011-ConnectorJ-Presentation.pdf" target="_blank">presentations</a> I gave at Java One and Silicon Valley Code Camp earlier this month.  It seems I significantly overestimated how much content I could effectively deliver in the time allotted, and left a few of my major points untouched.  These blog posts will try to rectify that.</p>
<p>The first major area I failed to cover in depth was really &#8220;Extension Points&#8221;, starting from slide #56.  There are four major extension points in Connector/J:</p>
<ul>
<li>Lifecycle Interceptors</li>
<li>Statement Interceptors</li>
<li>Exception Interceptors</li>
<li>Loadbalancing Strategies</li>
</ul>
<p>We&#8217;ll look at the first in this post.</p>
<p>Connection lifecycle events can be useful for instrumenting or debugging application database behavior, without changing application code.  In Connector/J, you can intercept the following lifecycle events by implementing com.mysql.jdbc.ConnectionLifecycleInterceptor:</p>
<ul>
<li>Connection creation (via the init() method)</li>
<li>Connection.commit()</li>
<li>Connection.rollback()</li>
<li>Connection.setAutoCommit()</li>
<li>Connection.close()</li>
<li>Connection.setCatalog()</li>
<li>Transaction start/end (via transactionBegun() and transactionCompleted() methods)</li>
<li>Connection.close()</li>
<li>Connection object destruction (via destroy() method)</li>
</ul>
<p>So, how might this be useful?  In the <a title="Demo code" href="http://mysqlblog.fivefarmers.com/wp-content/uploads/mysqlblog.fivefarmers.com/2011/10/demo.zip" target="_blank">demo code provided</a>, I implemented code that prints the stack trace when Connection.rollback() is called.  Perhaps you are trying to understand where rollbacks are coming from in your application &#8211; the demo code lets you do just that.  The steps are fully illustrated in the demo code:</p>
<ol>
<li>Create a lifecycle interceptor that implements com.mysql.jdbc.ConnectionLifecycleInterceptor.</li>
<li>Add logging in the rollback() method to track whatever you require.</li>
<li>Start the application and list the fully-qualified class name of the lifecycle interceptor you created in step #1 as the value for property, &#8220;connectionLifecycleInterceptors&#8221;.  In the demo code, this is found in demo.connectorj.LifecycleInterceptorExample at line 23:</li>
</ol>
<p>props.setProperty(&#8220;connectionLifecycleInterceptors&#8221;, &#8220;demo.connectorj.plugins.ExampleLifecycleInterceptor&#8221;);</p>
<p>That&#8217;s it!</p>
<p>What other lifecycle events might you be interested in tracking?  Well, you might be interested in tracking the time between transaction start and end times.  You might be interested to know how many times setAutoCommit() is called.  It&#8217;s convenient that you can do all of this without modifying application code.</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Connector/J Presentation at JavaOne and SVCC</title>
		<link>http://mysqlblog.fivefarmers.com/2011/10/09/connectorj-presentation-at-javaone-and-svcc/</link>
		<comments>http://mysqlblog.fivefarmers.com/2011/10/09/connectorj-presentation-at-javaone-and-svcc/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 19:56:04 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Connector/J]]></category>
		<category><![CDATA[JavaOne]]></category>
		<category><![CDATA[SVCC]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=94</guid>
		<description><![CDATA[I&#8217;ve uploaded both the presentation materials and demo code used in my JavaOne and Silicon Valley Code Camp presentations. Since I ran out of time at JavaOne, I&#8217;ll be writing blog posts later this coming week to cover the material I didn&#8217;t get a chance to complete there. presentation slides demo code UPDATE:  I&#8217;ve started [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve uploaded both the presentation materials and demo code used in my JavaOne and Silicon Valley Code Camp presentations. Since I ran out of time at JavaOne, I&#8217;ll be writing blog posts later this coming week to cover the material I didn&#8217;t get a chance to complete there.</p>
<ul>
<li><a href="http://mysqlblog.fivefarmers.com/wp-content/uploads/mysqlblog.fivefarmers.com/2011/10/2011-ConnectorJ-Presentation.pdf">presentation slides<br />
</a></li>
</ul>
<ul>
<li><a href="http://mysqlblog.fivefarmers.com/wp-content/uploads/mysqlblog.fivefarmers.com/2011/10/demo.zip">demo code</a></li>
</ul>
<p><strong>UPDATE</strong>:  I&#8217;ve started adding posts fleshing out the presentation materials, which I will index below:</p>
<ul>
<li><a title="Lifecycle interceptors" href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/">Extension points &#8211; lifecycle interceptors</a></li>
<li><a title="Statement interceptors" href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/">Extension points &#8211; statement interceptors</a></li>
<li><a href="http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%e2%80%93-exception-interceptors/">Extension points &#8211; exception interceptors</a></li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2011/10/09/connectorj-presentation-at-javaone-and-svcc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Debugging Communication Link Failure exceptions in Connector/J</title>
		<link>http://mysqlblog.fivefarmers.com/2010/09/06/debugging-communication-link-failure-exceptions-in-connectorj/</link>
		<comments>http://mysqlblog.fivefarmers.com/2010/09/06/debugging-communication-link-failure-exceptions-in-connectorj/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 05:20:49 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Connector/J]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=100</guid>
		<description><![CDATA[Have you seen error messages similar to the following: Communications link failure &#8211; Last packet sent to the server was X ms ago. Judging from the forums, many people have had problems with this.  Here&#8217;s a brief overview of the causes, and potential solutions. Generally speaking, this error suggests that the network connection has been [...]]]></description>
			<content:encoded><![CDATA[<p>Have you seen error messages similar to the following:</p>
<blockquote><p>Communications link failure &#8211; Last packet sent to the server was X ms ago.</p></blockquote>
<p>Judging from the <a href="http://forums.mysql.com/read.php?39,363162,363162#msg-363162" target="_blank">forums</a>, <a href="http://forums.mysql.com/read.php?39,199085,199085#msg-199085" target="_blank">many people</a> have <a href="http://forums.mysql.com/read.php?39,366594,366594#msg-366594" target="_blank">had problems</a> with <a href="http://forums.mysql.com/read.php?39,375546,375546#msg-375546" target="_blank">this</a>.  Here&#8217;s a brief overview of the causes, and potential solutions.</p>
<p>Generally speaking, this error suggests that the network connection has  been closed. There can be several root causes:</p>
<ul>
<li>Firewalls or routers may clamp down on  idle connections (the MySQL client/server protocol doesn&#8217;t ping).</li>
<li>The MySQL Server may be closing idle connections which exceed the wait_timeout or interactive_timeout threshold</li>
</ul>
<p>There&#8217;s a couple of useful diagnostic details which can be useful.  For starters, when a recent (5.1.13) version of Connector/J is used, you should see additional details around both the last packet <em><strong>sent</strong></em> and <em><strong>received</strong></em>.  Older versions may simply indicate the last time a packet was sent to the server, which is frequently zero ms ago.  That&#8217;s not terribly useful, and it may be that you just sent a packet, but haven&#8217;t received a packet from the server for 12 hours.  Knowing how long it&#8217;s been since Connector/J last received a packet from the server is useful information, so if you are not seeing this in your exception message, update your driver.</p>
<p>The second useful diagnostic detail shows up when Connector/J notices that the time a packet was last sent/received exceeds the wait_timeout or interactive_timeout threshold.  It will attempt to notify you of this in the exception message.</p>
<p>The  following can be helpful in avoiding such problems, but ultimately  network connections can be volatile:</p>
<ul>
<li>Ensure connections are valid when checked out of connection pool (use  query which starts with &#8220;/* ping */&#8221; *exactly* to execute <a href="http://mysqlblog.fivefarmers.com/2010/08/25/connector-j-ping/" target="_blank">lightweight  ping</a> instead of full query)</li>
<li>Minimize duration a Connection object is left idle while other application logic is executed</li>
<li>Explicitly validate Connection before using after being left idle for extended period of time</li>
<li>Ensure <a href="http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_wait_timeout" target="_blank">wait_timeout</a> and <a href="http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_interactive_timeout" target="_blank">interactive_timeout</a> are set sufficiently high</li>
<li>Ensure tcpKeepalive is enabled</li>
<li>Ensure that any configurable firewall or router timeout setting accounts for maximum expected idle connection time.</li>
<li>Make sure that you are not setting socketTimeout, or that it is set to a sufficiently high value to avoid socket timeouts.</li>
</ul>
<p>I&#8217;ve seen exception messages which indicate Connections being used after sitting idle for hours &#8211; sometimes days.  If you do this, make sure that you are explicitly testing the connection before using it after lengthy idle periods.  Network connections fail, and applications need to be prepared to handle that.  But expecting connections to survive extended periods where left idle and work magically when used again hours later is just asking for trouble.</p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2010/09/06/debugging-communication-link-failure-exceptions-in-connectorj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Workbench called me a dummy!</title>
		<link>http://mysqlblog.fivefarmers.com/2010/09/01/workbench-called-me-a-dummy/</link>
		<comments>http://mysqlblog.fivefarmers.com/2010/09/01/workbench-called-me-a-dummy/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 05:16:44 +0000</pubDate>
		<dc:creator>Todd Farmer</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[workbench]]></category>

		<guid isPermaLink="false">http://mysqlblog.fivefarmers.com/?p=95</guid>
		<description><![CDATA[Seriously, it did.  Sorta. I use Workbench for my daily work, and it&#8217;s a great tool.  If you haven&#8217;t tried the 5.2 release yet, you should.  While performing some maintenance, I happened to issue a DELETE statement against a table which had no indexes (it was 10 rows), and Workbench complained: Error Code: 1175 You [...]]]></description>
			<content:encoded><![CDATA[<p>Seriously, it did.  Sorta.</p>
<p>I use Workbench for my daily work, and it&#8217;s a great tool.  If you haven&#8217;t tried the<a href="http://dev.mysql.com/downloads/workbench/5.2.html" target="_blank"> 5.2 release</a> yet, you should.  While performing some maintenance, I happened to issue a DELETE statement against a table which had no indexes (it was 10 rows), and Workbench complained:</p>
<p><code>Error Code: 1175<br />
You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column</code></p>
<p>It turns out this is a new feature in 5.2.26 (and is still there in 5.2.27) &#8211; Workbench now uses the equivalent of <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-command-options.html#option_mysql_safe-updates" target="_blank">&#8211;safe-updates</a> mode for the mysql command-line client (also known as the &#8211;i-am-a-dummy option &#8211; seriously).  This wasn&#8217;t exactly convenient for me, especially since the DELETE was part of a larger script which I then had to revise and step through manually after it failed, but there&#8217;s an easy way to change this behavior.  If you&#8217;re like me, you might consider disabling this:</p>
<ul>
<li>Go to Edit -&gt; Preferences</li>
<li>Select the SQL Editor tab</li>
<li>Uncheck &#8220;Forbid UPDATE and DELETE statements without a WHERE clause (safe updates)&#8221;</li>
</ul>
<p>Despite the text, the &#8211;safe-updates mode affects more than UPDATE and DELETE statements without WHERE clauses &#8211; it requires such statements to explicitly use indexes.</p>
<p>I&#8217;m changing this behavior on my installation before I run into other problems.</p>
<p>I&#8217;m no dummy.  <img src='http://mysqlblog.fivefarmers.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://mysqlblog.fivefarmers.com/2010/09/01/workbench-called-me-a-dummy/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

