mysql:15421
From: "Suzuki, Ikuo" <"Suzuki, Ikuo" <ikuo.suzuki@xxxxxxxxxx>>
Date: Tue, 9 Nov 2010 11:47:13 +0900
Subject: [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 @xxxxxxxxxx (mysql-5.1.47 ndb-7.1.8, Nodegroup: 0)
id=4 @xxxxxxxxxx (mysql-5.1.47 ndb-7.1.8, Nodegroup: 0, Master)
[ndb_mgmd(MGM)] 2 node(s)
id=1 @xxxxxxxxxx (mysql-5.1.47 ndb-7.1.8)
id=2 @xxxxxxxxxx (mysql-5.1.47 ndb-7.1.8)
[mysqld(API)] 2 node(s)
id=5 @xxxxxxxxxx (mysql-5.1.47 ndb-7.1.8)
id=6 @xxxxxxxxxx (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@xxxxxxxxxx
--------------------------------------------------------