Search code examples
javaapacheembedded-database

Apache embedded derby replication - slave instance not returning the connection


I am trying to setup replication in apache embedded derby database. I am following the DerbyAdmin guide to implement the same -

As per this I have to start slave first and then master database. But as soon as I try to getConnection on slave derby instance method call gets stuck. It never return a connection. Following is the code for the same -

public static Connection getConnection(){
    Class.forName("org.apache.derby.jdbc.EmbeddedDriver");  
    String url = "jdbc:derby:<slave db location>;startSlave=true";
    System.out.println("about to fetch connection");
    Connection con= null;
    try{
        con=DriverManager.getConnection(url, "root", "root");
    }catch(Exception e){
        e.printStackTrace();
    }
    System.out.println("return con -"+con);
    return con;
}

output

about to fetch connection

Just to ensure if all the derby lib are included in the project I tried fetching the connection without startSlave=true attribute and it did return the connection.

public static Connection getConnection(){
    Class.forName("org.apache.derby.jdbc.EmbeddedDriver");  
    String url = "jdbc:derby:<slave db location>;";
    System.out.println("about to fetch connection");
    Connection con= null;
    try{
        con=DriverManager.getConnection(url, "root", "root");
    }catch(Exception e){
        e.printStackTrace();
    }
    System.out.println("return con -"+con);
    return con;
}

output

about to fetch connection

return con -org.apache.derby.impl.jdbc.EmbedConnection@2022850302 (XID = 420), (SESSIONID = 1), (DATABASE = I:/R&D/derby replication/Slave/replMaster), (DRDAID = null)

I tried checking derby.log file but log file is also empty. Let me know what is going wrong.

Thanks in advance.


Solution

  • After working on it for very long time I found slave is suppose to work like this.

    Unlike my assumption we have to start master first and then slave.

    Following are the steps which I performed to make it work-

    1. Start the derby in embedded mode call it instance masterCandidate and freeze the database by calling below SP-

      call SYSCS_UTIL.SYSCS_FREEZE_DATABASE()

    2. Copy paste the database (derby folder) to slave location (note do not stop this derby instance)

    3. Now start the derby with following URL call it instance slaveCandidate-

      jdbc:derby:<slave db location>;startSlave=true don't wait for method to return the connection it will return below exception when we will connect master derby instance-

    ERROR XRE08: Replication slave mode started successfully for database ''. Connection refused because the database is in replication slave mode.

    1. Create a new connection to the masterCandidate instance with startMaster attribute and make it master -

      jdbc:derby:;startMaster=true;slaveHost=slaveHost;slavePort=slavePort

    2. Now you are ready to read/write on master, from now on no need to pass startMaster=true attribute while the master connection

    As soon as masterCandidate instance goes down slave automatically becomes master.

    Till master is alive fetching a connection from slave always return above mentioned(point 3) exception.

    As soon as master goes down we can fetch connection on slaveCandidate without passing attribute.

    jdbc:derby:<slave db location>