Asynchronous Replication

As mentioned in the HA Applications page, in asynchronous or lazy replication, updates are propagated to replica nodes asynchronously and after the transaction commits on the master node. These updates are applied to replica nodes as separate transactions which can improve transaction responsiveness, however replica read-only transactions run the risk of operating with stale data. Because replica databases are available to the replica applications for read-only access, replica applications may read ‘stale’ data if transactions were committed at the master but not yet propagated to the replica.

Asynchronous replication is enabled in C/C++ applications by setting the mode_flags element to MCO_HAMODE_ASYNCH in the master:

 
    mco_HA_master_params_t MasterParams;
    mco_HA_master_params_init( &MasterParams );
    MasterParams.mode_flags = MCO_MASTER_MODE | MCO_HAMODE_ASYNCH;
    …
    mco_HA_set_master_params( db, &MasterParams );
     

In C# and Java applications:

 
    MasterConnection.Parameters MParams = new MasterConnection.Parameters(
    MasterConnection.MCO_HAMODE_ASYNCH);
    con.SetReplicationMode( MParams );
     

The master application must also create a memory device to accommodate the asynchronous buffer in either shared or conventional memory. The size of the buffer is defined in bytes (not in a number of transactions) and is processed in a separate task within the eXtremeDB High Availability runtime.

The following code snippet demonstrates how the async buffer can be initialized in C/C++ applications:

 
    /****************************************************
    * Asynchronous commit thread
    * It sends transaction data to replicas using the async_databuf
    ****************************************************/
    void AsyncCommit( sample_task_t * descriptor )
    {
        /* wait for async commit event and output the portion of data to the stream */
        while (mco_HA_async_send_data_to_replicas(descriptor->db_connection) ==
            MCO_S_OK)
        sample_sleep(1);
    }
     
    /****************************************************
    /* Snippet from the master main that initializes async replication */
    /****************************************************
    mco_HA_master_params_init( &MasterParams );
    MasterParams.mode_flags = MCO_MASTER_MODE | MCO_HAMODE_ASYNCH;
     
    /* assign the device as an asynchronous buffer */
    MasterParams.async_databuf.assignment = MCO_MEMORY_ASSIGN_HA_ASYNC_BUF;
     
    /* set the device size */
    MasterParams.async_databuf.size       = ASYNC_DATABUF_SIZE;
    if ( runtime_info.mco_shm_supported )
    {
        /* set the device as a shared named memory device */
        MasterParams.async_databuf.type       = MCO_MEMORY_NAMED;
         
        /* set memory name */
        sprintf( MasterParams.async_databuf.dev.named.name, "%s-ha", db_name);
        MasterParams.async_databuf.dev.named.flags = 0;  /* zero flags */
         
        /* set mapping address or zero it out */
        MasterParams.async_databuf.dev.named.hint  = 0;
    }
    else
    {
        /* set a conventional memory device */
        MasterParams.async_databuf.type         = MCO_MEMORY_CONV;
        MasterParams.async_databuf.dev.conv.ptr = (void*)malloc(ASYNC_DATABUF_SIZE);
    }
     
    mco_HA_set_master_params(db, &MasterParams); /*  set MASTER mode */
     
    /* start the ListenToReplicas thread*/
    sample_start_connected_task(&listen_task, ListenToReplicas, db_name, &ha );
     
    /* start the AsyncCommit thread*/
    sample_start_connected_task(&async_commit_task, AsyncCommit, db_name, 0 );
     

A similar C# implementation would look like the following:

 
    // Asynchronous commit thread that sends transaction data to replicas,
    // using async databuf
    public void Replicate()
     {
        MasterConnection con = new MasterConnection(db);
        while (con.AsyncSendDataToReplicas())
         {
            Thread.Sleep(REPLICATION_PERIOD);
        }
        con.Disconnect();
    }
     
    Master()
    {
        //****************************************************
        // Snippet from the master main that initializes async replication
        //****************************************************
        // set HA mode
         
        MasterConnection.Parameters MParams = new
        MasterConnection.Parameters(
        MasterConnection.MCO_HAMODE_ASYNCH );
        MasterParams.AsyncBuf = new
        Database.PrivateMemoryDevice( Database.Device.Kind.AsyncBuffer,
        ASYNC_BUF_SIZE );
        con.SetReplicationMode( MParams );
        MParams.listening = true;
         
        // start listen and async. commit threads
        Thread listenThread = new Thread(new ThreadStart(Listen));
        Thread replicateThread = new Thread(new ThreadStart(Replicate));
        listenThread.Start();
        replicateThread.Start();
     

As with synchronous replication, no additional replication logic is required in either master or replica applications; all replication operations are managed internally by the eXtremeDB High Availability runtime.

Replication Event Notifications

Whether using synchronous or asynchronous replication, replica application instances can be configured to receive notification of various synchronization and replication events. The possible notification events are defined as follows:

MCO_REPL_NOTIFY_CONNECTED
Replica successfully connected.
MCO_REPL_NOTIFY_CONNECT_FAILED
Replica connection failed.
MCO_REPL_NOTIFY_DB_EQUAL
The database is the same, no need to load the database.
MCO_REPL_NOTIFY_DB_LOAD_BEGIN
Begin loading the database.
MCO_REPL_NOTIFY_DB_LOAD_FAILED
Error loading the database; param1 on the notification callback is the MCO_RET return code.
MCO_REPL_NOTIFY_DB_LOAD_OK
Database successfully loaded; param1 on the notification callback is the MCO_E_HA_REPLICA_STOP_REASON code.
MCO_REPL_NOTIFY_DB_CREATION_FAILED
Database creation failed" notification; param1 on the notification callback is the MCO_RET return code.
MCO_REPL_NOTIFY_COMMIT_FAILED
Error during a transaction commit; param1 on the notification callback is the MCO_RET return code.
MCO_REPL_NOTIFY_REPLICA_STOPPED
Replication stopped.
MCO_REPL_NOTIFY_HOTSYNC
Hotsynch process beginning.
MCO_REPL_NOTIFY_EOHOTSYNC
Hotsynch process completed.
MCO_REPL_NOTIFY_STATEFUL_SYNC
Stateful synch process beginning.
MCO_REPL_NOTIFY_STATEFUL_SYNC_END
Stateful synch process completed.
MCO_REPL_NOTIFY_MASTER_DB_EXTENDED
The master has extended the database memory.

Replication event notifications in C/C++ replica applications are enabled by setting the MCO_HAMODE_REPLICA_NOTIFICATION bit in the mode_flags element and the function address of the event handler in the notifying_callback element in the mco_HA_replica_params_t structure passed to mco_HA_attach_master(). In C# and Java applications the mode flag and callback are specified in the ReplicaConnection.Parameters sent to method ReplicaConnection.AttachMaster().