Skip Headers
Oracle® Communications Calendar Server System Administrator's Guide
Release 7.0.5

E54935-01
Go to Documentation Home
Home
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

12 Configuring a High-Availability Database

Oracle Communications Calendar Server relies on native capabilities offered by MySQL Server and Oracle GlassFish Server for a high-availability solution. This chapter provides details on one such scenario: setting up replication of MySQL Server by using the JDBC Connector/J driver in GlassFish Server. If you want more sophisticated solutions for MySQL Server high availability, refer to the MySQL Server documentation, for example, the High Availability and Scalability chapter in MySQL 5.5 Reference Manual.

Other high availability solutions are also known in the MySQL Server community. You should decide which solution best fits your deployment and requirements.

Note:

The examples in this information are intended for only one Calendar front end per Calendar back end.

Topics:

Overview of MySQL Server Asynchronous Replication

MySQL Server, as well as third parties, offer a wide range of high availability options ranging from completely manual to high-end MySQL Server HA solutions. MySQL Server implements manual asynchronous replication, provided within the product itself. This has been in use for some time and is stable. Failover, failback, and resynchronizing nodes, and adding a node, are all done manually. See the topic on replication in MySQL 5.5 Reference Manual for more information.

MySQL Server 5.5 provides semi-synchronous replication in which the master node tries to sync with at least one other node before completing the request, subject to a timeout.

MySQL Server Asynchronous Replication Example

This section describes a simple example of MySQL Server asynchronous replication configuration for MySQL Server 5.5.8 consisting of one master and one slave.

To configure asynchronous replication:

  1. Edit the /etc/my.cnf file for both master and slave MySQL Server hosts as follows:

    [mysqld]
     basedir = /opt/mysql/mysql
     datadir = /var/opt/sun/comms/davserver/db
     default-storage-engine = InnoDB
     character-set-server = utf8
     transaction-isolation = READ-COMMITTED
     server-id=1
     log-bin=mysql-bin
     innodb_flush_log_at_trx_commit=1
     sync_binlog=1
     binlog-format=ROW
     skip-name-resolve
    

    Note the following:

    • server-id: The unique id for each server numbered greater than 0. (The master here is 1, the slave is 2.)

    • log-bin: Turns on binary logging for replication.

    • innodb_flush_log_at_trx_commit: Recommended.

    • sync_binlog: Recommended.

    • binlog-format: Must be ROW because of transaction-isolation level used in Calendar Server and MySQL Server 5.5.8.

    • skip-name-resolve: This is a workaround if you experience the following slave error:

      ERROR 1042 (HY000): Can't get hostname for your address.
      
    • Do not set log-slave-updates.

  2. Follow the replication procedures described in the "Replication" chapter of MySQL 5.5 Reference Manual to complete the configuration.

    In this example, both nodes have a log-bin and do not have log-slave-updates. Some procedures in the "Replication" chapter might include log-slave-updates for specific purposes, but they have been left out from these instructions, assuming most of the time a failed node retains its data and does not need the log-slave-updates data on the other node. These instructions also assume that the binary log removal over time might indicate a node that lost its data, and so is not able to get all data from the other node's logs anyhow.

MySQL Server Two-Way Replication Example

This section describes an example of a manually-controlled HA configuration. It is similar to the preceding asynchronous replication example, except that each node is set to be the slave of the other. Because both nodes have turned on binary logs, each node logs the data that comes to it. The configuration is the same as asynchronous (assuming the replication user exists on both nodes).

This is not very different from one-way synchronization considering that even in master-slave replication you can set up the master as a slave to the original slave when you are trying to resynchronize a failed master.

However, another way of using two-way replication is to assign specific client data to each node, and use the opposite node for the slave. The result is that each node replicates the other in parallel. It's important that any specific client data be assigned to only one master at a time or else inconsistencies might occur.

Replication Synchronization Issues

When managing MySQL Server replication, it is important to understand synchronization issues. If data arrives at one node in a different order as it does in a replicated node, replication might fail and halt.

For example, given one-way replication, imagine that the master receives data called "dog" and at the same time a client believing the master is not available sends "cat" to the slave. The master has "dog" in row 1, and the slave has cat in row 1. The data between the nodes has become inconsistent. When the slave receives "dog" from the master relay, it is not able to put it into row 1 as it exists on the master. The nodes become inconsistent and replication fails and halts.

MySQL Server has no internal mechanism to synchronize this automatically, and when the MySQL Server server comes up as an active slave, it accepts new connections and also tries to catch up with the master in parallel.

These issues need to be considered when executing manual replication procedures as well as when using automatic functions of any other program.

Using the Multi-Host Failover Feature of JDBC Connector/J

JDBC Connector/J for MySQL Server has various capabilities for load balancing and high availability. The example configuration in this section shows how to use JDBC Connector/J for MySQL Server for an automatic failover, assuming a manual resynchronization and failback. This example assumes the use of MySQL Server 5.5.8.

  1. On the GlassFish Server, make the following connector configuration:

    Note:

    The following information pertains to configuring the Calendar Server database. You might also want to configure the same for the iSchedule database if it exists on the same host.
    • Enable connection validation.

    • Enable on any failure close all connection.

    • Transaction isolation: Guaranteed read-committed

  2. Use the following properties:

    user mysql
    password mysql
    URL jdbc:mysql://masterhost:3306,slavehost:3306/caldav
    autoReconnect true
    failOverReadOnly false
    autoReconnectForPools true
    roundRobinLoadBalance false
    secondsBeforeRetryMaster 2147483647
    queriesBeforeRetryMaster 2147483647
    
  3. For more information, refer to the "MySQL Server Connector/J" chapter on configuration parameters in MySQL 5.5 Reference Manual. The MySQL Server replication configuration is two-way with each node being both a master and slave to the other. The example shows a failure on master1, and master1 failing over to master2.

    Note:

    secondsBeforeRetryMaster and queriesBeforeRetryMaster are set to a very large value to prevent GlassFish Server from failing back to master1 once it has experienced a failover. This prevents new data from being written to master1 before master1 has had a chance to catch up. Otherwise data might become inconsistent.

Failover and recovering of this example works as follows:

  1. Fail over.

    You need a way to be alerted that a node has gone down. Once you are alerted, you must address the situation quickly to control when master1 comes back up and is resynchronzied and new connections are made to it.

  2. Recover master1.

    If master1's data is damaged or lost, you must reload master1 from master2 described in the MySQL Server replication notes.

    • Also, if master1 has data that did not make it to master2 before it failed over, it might be easier to reload master1. This situation is less likely if semi-synchronous replication is used.

    • You can check the binary log position on master1 with show master status, compared to master2's show slave status, to determine if master2 received all of master1's data without error.

  3. Bring back master1.

    At this point it, might be useful to shut down GlassFish Server to make sure that master1 does not receive new connections before it can resynchronize with master2. Other procedures are possible, but master1 needs to resynchronize before it receives new GlassFish Server connections.

  4. Bring up master1.

    Verify it has resynchronized with master2 by using show master status on master2 versus show slave status on master1.

  5. Once master1 is caught up, you can restart GlassFish Server and it should return connections to master1, effectively failing back.

Note:

Be sure to verify, test, and refine any HA procedure before putting it into production.

Test for MySQL Server Asynchronous Replication (Manual)

The test described in this section uses the following software and servers:

  • MySQL Server 5.5.8 Enterprise Version

  • JDBC Connector/J 5.1.5

  • Two MySQL Server servers named Master and Slave

  • Oracle Solaris 10

  • GlassFish Server 2.1

  1. On host Master, create a user named mysql that has replication permission on Master. In this case, user mysql is the same user name that Calendar Server uses itself to connect to MySQL Server.

    GRANT REPLICATION SLAVE ON *.* TO 'mysql'@'%';
    
  2. On both hosts Master and Slave, edit the /etc/my.cnf config file as follows.

    [mysqld]
     basedir = /opt/mysql/mysql
     datadir = /var/opt/sun/comms/davserver/db
     default-storage-engine = InnoDB
     character-set-server = utf8
     transaction-isolation = READ-COMMITTED
     server-id=1
     log-bin=mysql-bin
     innodb_flush_log_at_trx_commit=1
     sync_binlog=1
     binlog-format=ROW
     skip-name-resolve
    
  3. Modify the GlassFish Server and JDBC Connector/J configuration to fail over from Master to Slave.

    The following is for the caldav database. Do the same for the iSchedule database.

    DataSource Classname: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
    Resource Type: javax.sql.DataSource
    
    Enable 'connection validation'
    Enable 'on any failure close all connection'
    transaction isolation: Guaranteed
    read-committed
    
    user                    mysql
    password                mysql
    URL                     jdbc:mysql://Master:3306,Slave:3306/caldav
    autoReconnect           true
    failOverReadOnly        false
    autoReconnectForPools   true
    roundRobinLoadBalance   false
    secondsBeforeRetryMaster 2147483647
    queriesBeforeRetryMaster 2147483647
    

    secondsBeforeRetryMaster and queriesBeforeRetryMaster are set to a high value to prevent GlassFish Server and Connector/J from failing back if the master were to come back up.

  4. Initialize both hosts Master and Slave.

    1. Run the following command, if the servers were previously functioning as a slave:

      stop slave;
      
    2. Remove all Calendar Server data from both hosts so that the databases are synchronized.

      For example:

      ./davadmin db init -H localhost -t mysql -u mysql -d caldav
      ./davadmin db init -H localhost -t mysql -u mysql -d ischedule
      

      Substitute your names for caldav and ischedule.

      Caution:

      These commands completely remove the calendar data.
    3. On both Master and Slave, run the following command:

      reset slave;
      
    4. On both Master and Slave, run the following command:

      reset master;
      
  5. Set up Slave to be synchronized with Master.

    1. Run the following command on Master:

      show master status;   
      
      File = mysql-bin.000001 
      Position = 107 
      
    2. Note the File and Position to set parameters on Slave.

  6. Run the following command on Slave:

    CHANGE MASTER TO  
    MASTER_HOST='Master',  
    MASTER_USER='mysql',  
    MASTER_PASSWORD='mysql',  
    MASTER_LOG_FILE='mysql-bin.000001',  
    MASTER_LOG_POS=107; 
    
  7. Start Slave:

    start slave;
    
  8. Restart GlassFish Server to load Calendar Server.

  9. Verify both Master and Slave.

    use caldav; 
    select count(*) from Resources; 
    

    There should be one row after GlassFish Server starts.

  10. Run data through Calendar Server (that is, use Calendar Server to create or change events, and so on, to cause calendar data to be stored).

  11. Verify that data is accumulating on both Master and Slave.

    For example, use the following MySQL commands to look at data in the tables:

    use caldav;
    select * from Resources;
    

    You can also use this command:

    select count(*) from Resources;
    

    You can also use the following status commands:

    show master status;
    show slave status;
    
  12. Stop Master and observe the failover.

    The failover could take up to 60 seconds or more, as the connections time out.

  13. Use the following command to observe that Slave is continuing to operate:

    select count(*) from Resources;
    

Test for MySQL Server Two-Way Replication with Connector/J Failover

The test described in this section uses the following software and servers:

  • MySQL Server 5.5.8 Enterprise Version

  • JDBC Connector/J 5.1.5

  • Two MySQL Server servers named Master1 and Master2

  • Oracle Solaris 10

  • GlassFish Server 2.1 1

  1. On both hosts Master1 and Master2, create a user that has replication permission.

    In this case, user mysql is the same user name that Calendar Server uses itself to connect to MySQL Server.

  2. Run the following command both Master1 and Master2.

    GRANT REPLICATION SLAVE ON *.* TO 'mysql'@'%'; 
    
  3. On both hosts Master1 and Master2, edit the /etc/my.cnf config file as follows.

    [mysqld]
     basedir = /opt/mysql/mysql
     datadir = /var/opt/sun/comms/davserver/db
     default-storage-engine = InnoDB
     character-set-server = utf8
     transaction-isolation = READ-COMMITTED
     server-id=1
     log-bin=mysql-bin
     innodb_flush_log_at_trx_commit=1
     sync_binlog=1
     binlog-format=ROW
     skip-name-resolve
    
  4. Modify the GlassFish Server and JDBC Connector/J configuration to fail over from Master1 to Master2. The following is for the caldav database, you should also do the same for the iSchedule database.

    DataSource Classname: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
    Resource Type: javax.sql.DataSource
    
    Enable 'connection validation'
    Enable 'on any failure close all connection'
    transaction isolation: Guaranteed
    read-committed
    
    user                    mysql
    password                mysql
    URL                     jdbc:mysql://Master1:3306,Master2:3306/caldav
    autoReconnect           true
    failOverReadOnly        false
    autoReconnectForPools   true
    roundRobinLoadBalance   false
    secondsBeforeRetryMaster 2147483647
    queriesBeforeRetryMaster 2147483647
    

    secondsBeforeRetryMaster and queriesBeforeRetryMaster are set to a high value to prevent GlassFish and Connector/J from failing back if the master were to come back up.

  5. Initialize both hosts Master1 and Master2:

    1. Run the following command:

      stop slave;
      
    2. Remove all Calendar Server data from both hosts so that the databases are synchronized. For example:

      ./davadmin db init -H localhost -t mysql -u mysql -d caldav
      ./davadmin db init -H localhost -t mysql -u mysql -d ischedule
      

      Substitute your names for caldav and ischedule.

      Caution:

      These commands completely remove the calendar data.
    3. On both Master1 and Master2, run the following command:

      reset slave;
      
    4. On both Master1 and Master2, run the following command:

      reset master
      
  6. Run the following command to verify file and position on each master:

    show master status;
    both show: mysql-bin.000001 107
    
  7. Run the following commands to set each master to be a slave to the other:

    1. On Master2:

      CHANGE MASTER TO  
      MASTER_HOST='Master1',  
      MASTER_USER='mysql',  
      MASTER_PASSWORD='mysql',  
      MASTER_LOG_FILE='mysql-bin.000001',  
      MASTER_LOG_POS=107; 
      
    2. On Master1:

      CHANGE MASTER TO  
      MASTER_HOST='Master2',  
      MASTER_USER='mysql',  
      MASTER_PASSWORD='mysql',  
      MASTER_LOG_FILE='mysql-bin.000001',  
      MASTER_LOG_POS=107; 
      
  8. Start slave connection on both hosts Master1 and Master2:

    start slave;
    
  9. Restart GlassFish Server to load Calendar Server.

  10. Verify both hosts Master1 and Master2:

    use caldav;
    select count(*) from Resources;
    

    There should be one row after GlassFish Server starts.

  11. Run data through Calendar Server (that is, use Calendar Server to create or change events, and so on, to cause calendar data to be stored).

  12. Verify that data is accumulating on both Master and Slave.

    For example, use the following MySQL commands to look at data in the tables:

    use caldav;
    select * from Resources;
    

    You can also use this command:

    select count(*) from Resources;
    

    You can also use the following status commands:

    show master status;
    show slave status;
    
  13. Stop Master1 and observe the failover.

    The failover could take up to 60 seconds or more, as the connections time out.

  14. Use this to observe the slave continuing:

    select count(*) from Resources;
    
  15. Stop GlassFish Server (to stop incoming client connections and data).

  16. Bring Master1 online and allow it to sync as a slave to Master2.

  17. Verify that Master1 synced as a slave to Master2.

    • On Master1:

      show slave status
      

      Make sure that there are no errors and note the slave position, for example, mysql-bin.000001 1827176.

    • On Master2:

      show master status
      mysql-bin.000001 1827176
      

      Verify this position with the one that you noted on Master1.

  18. Verify that Master2 is still synced with Master1.

    • On Master2:

      show slave status
      

      Make sure that there are no errors and note the slave position, for example, mysql-bin.000002 107.

    • On Master1:

      show master status
      mysql-bin.000002 107
      

      Verify this position with the one that you noted on Master2.

  19. Verify Row Count on both Master1 and Master2 by comparing the count from each machine:

    select count(*) from Resources;
    
  20. Start GlassFish Server and start incoming client data.

  21. Verify That Master1 is in action again, and that Master2 is following.

    • On Master1:

      show master status;
      

      Verify that the position is increasing as master.

    • On Master2:

      show master status;
      

      Verify that the position is not increasing.

    • On both Master1 and Master2:

      select count(*) from Resources;