Bug #11879 ReplicationDriver fails when switching between master and slaves
Submitted: 12 Jul 2005 9:21 Modified: 17 Oct 2005 19:42
Reporter: hannes wallnoefer Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:3.1.10 OS:
Assigned to: Mark Matthews CPU Architecture:Any

[12 Jul 2005 9:21] hannes wallnoefer
Description:
I'm trying to use the ReplicationDriver with  Connector/J 3.1.10 as described in 

http://dev.mysql.com/doc/connector/j/en/cj-replication-connection.html

When I try to set a connection to readonly in order to make it use the slave connection, I get the following exception:

java.sql.SQLException: Catalog can not be null
        at com.mysql.jdbc.Connection.setCatalog(Connection.java:4912)
        at com.mysql.jdbc.ReplicationConnection.switchToSlavesConnection(ReplicationConnection.java:461)
        at com.mysql.jdbc.ReplicationConnection.setReadOnly(ReplicationConnection.java:382)

The strange thing is that a getCatalog() invoked on the connection immediately before invoking setReadOnly(true) returns "gobi", i.e. the catalog is correctly set and not null. 

How to repeat:
I'm using DriverManager.getConnection() to get the connection. The registered driver class is com.mysql.jdbc.ReplicationDriver, the URL for the connection is:

url = jdbc:mysql://localhost:3307,localhost:3308/gobi

The additional properties passed to DriverManager.getConnection are:

user=foo
password=foo
autoReconnect=true
roundRobinLoadBalance=true

Suggested fix:
A look at ReplicationConnection.switchToSlavesConnection() shows the following:

                if (masterCatalog != null && !masterCatalog.equals(slaveCatalog)) {
                        this.slavesConnection.setCatalog(masterCatalog);
                } else if (slaveCatalog != null) {
                        this.slavesConnection.setCatalog(null);
                }

in other words, if both masterCatalog and slaveCatalog are already not null and set to the same string, we falsely go into the else branch and try to null out the slaveCatalog. One way to fix this would be to replace this with this:
                
                if (masterCatalog != null) {
                        if (!masterCatalog.equals(slaveCatalog)) {
                                this.slavesConnection.setCatalog(masterCatalog);
                        }
                } else if (slaveCatalog != null) {
                        this.slavesConnection.setCatalog(null);
                }
[12 Jul 2005 11:22] Vasily Kishkin
Could you please provide test case ?
[12 Jul 2005 11:47] hannes wallnoefer
This testcase reproduces the bug for me. You'll have to edit the url, properties, statements in order to make it run for you.

Attachment: ReplicationDriverTest.java (text/x-java), 1.42 KiB.

[12 Jul 2005 12:25] Mark Matthews
I can write a testcase for this, it's straightforward (two lines or so). Once that's done, I'll set status accordingly.
[12 Jul 2005 12:31] hannes wallnoefer
I uploaded a testcase to the Files section.
[1 Aug 2005 0:06] Michael Platzer
since the fix seems to be a one-liner is there any chance that this makes it into the official connector/j distribution (or into cvs) anytime soon?
[1 Aug 2005 0:43] Mark Matthews
It should actually already be in the nightly builds of 3.1 at http://downloads.mysql.com/snapshots.php#coonector-j
[3 Aug 2005 7:19] Keita Kitamura
I still get the same exception when using conn.setReadOnly(false).
I'm not sure, but guess the method switchToMasterConnection needs to be fixed too.
[3 Aug 2005 21:47] Mark Matthews
Okay, this issue should be fixed now. Testing the Aug-04 nightly build (available after 00:00 GMT) should work.