2010年11月 9日

[mysql 15421] Connector/Jのフェイルオーバー時の接続がReadOnlyになる

日本ユニシス(株)でSEとして働いている鈴木と申します。
JavaによるWebアプリ開発経験が5年ほどありますが、
MySQLを利用し始めたのは1ヶ月ほど前からです。

MySQL ClusterとConnector/Jを利用してフェイルオーバーを
を実現しようとしているのですが、
failOverReadOnly=falseにしているにも関わらず接続が
Read Onlyになる問題で困っています。


クラスタは2台で形成しており、両方のマシンに
それぞれ管理ノード、SQLノード、データノードの機能を持たせた
以下の構成となっています。

【クラスタ構成】
========================================================================
ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=3 @10.32.152.114 (mysql-5.1.47 ndb-7.1.8, Nodegroup: 0)
id=4 @10.32.152.115 (mysql-5.1.47 ndb-7.1.8, Nodegroup: 0, Master)

[ndb_mgmd(MGM)] 2 node(s)
id=1 @10.32.152.114 (mysql-5.1.47 ndb-7.1.8)
id=2 @10.32.152.115 (mysql-5.1.47 ndb-7.1.8)

[mysqld(API)] 2 node(s)
id=5 @10.32.152.114 (mysql-5.1.47 ndb-7.1.8)
id=6 @10.32.152.115 (mysql-5.1.47 ndb-7.1.8)
========================================================================

また、各ソフトウェアのバージョンは以下のとおりです。
【バージョン】
・MySQL 5.1.47
・MySQL Cluster 7.1.8
・Connector/J 5.1.13

前述の環境下でSQLノードの片方(id=5, 10.32.152.114)を停止して、
以下のプログラムを実行すると問題が再現します。

【プログラム】
========================================================================
package jp.co.unisys.mysql;

import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Properties;

import com.mysql.jdbc.Connection;

public class Test {
public static void main(String[] args) throws Exception {
System.out.println("データのアップデートを開始します。");
String url = "jdbc:mysql://10.32.152.114:3306,10.32.152.115:3306/test";
Properties prop = new Properties();
prop.put("autoReconnect", "true");
prop.put( "roundRobinLoadBalance", "true" );
prop.put("failOverReadOnly", "false");

Class.forName("com.mysql.jdbc.Driver");
Connection conn = (Connection) DriverManager.getConnection(url, prop);
PreparedStatement ps = conn
.prepareStatement("UPDATE dt_2 SET name=? WHERE id=1");
try {
for (int index = 0;; index++) {
ps.setString(1, "New Name " + index);
ps.executeUpdate();
System.out.println("New Name " + index + " に更新しました。");
}
} finally {
ps.close();
conn.close();
}
}
}
========================================================================

期待する結果は10.32.152.114が落ちているため、
代わりに10.32.152.115に接続しUPDATEクエリを実行することなのですが、
実際には以下のように接続がRead Onlyという理由でUPDATEクエリが実行できま
せん。

【結果】
========================================================================
> java -jar test-5.1.13.jar
データのアップデートを開始します。
Exception in thread "main" java.sql.SQLException: Connection is
read-only. Queries leading to data modification are not allowed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
at
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2360)
at
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2327)
at
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2312)
at jp.co.unisys.epi.mysql.Test1.main(Test1.java:29)
========================================================================

ところで、Googleでバグトラッカーの過去ログを検索したところ、
以下の投稿をみつけました。

MySQL Bugs: #34946: failoverReadOnly=false with multimaster does not work
< http://bugs.mysql.com/bug.php?id=34946>;

これを読むと、フェイルオーバーは必ずRead Onlyになるように
仕様変更されたので、failoverReadOnlyのフラグは機能せず、
廃止すべきだと言っていると思います。

この投稿から過去のバージョンでは挙動が違うのではと思い、
試しにConnector/Jのバージョンを5.0.8に変更して、
先ほどと同様のプログラムを実行してみました。
すると、UPDATEクエリを実行することができました。

【結果(一部)】
========================================================================
> java -jar test-5.0.8.jar
データのアップデートを開始します。
New Name 0 に更新しました。
New Name 1 に更新しました。
New Name 2 に更新しました。
New Name 3 に更新しました。
New Name 4 に更新しました。
New Name 5 に更新しました。
New Name 6 に更新しました。
New Name 7 に更新しました。
New Name 8 に更新しました。
New Name 9 に更新しました。
========================================================================

この結果から、片方のSQLノードが落ちた場合のフェイルオーバーは
Connector/Jの5.0.8を使えば実現できそうだと考えているのですが、
そもそも、なぜ5.0.8から5.1.13の間でこうした仕様変更がおこなわれたのか
を知りたいと思っています。

このあたりの事情をご存じの方はいらっしゃいましたら、
教えていただけないでしょうか?
どうぞよろしくお願い申し上げます。

以上
--------------------------------------------------------
日本ユニシス株式会社
ICTサービス基盤開発部 ソリューション開発室
開発3グループ
鈴木 生雄
tel:050-3132-6999 mailto:ikuo.suzuki@xxxxx
--------------------------------------------------------


投稿者 xml-rpc : 2010年11月 9日 11:47
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/99979
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。