Synchronous replication using the time-cognizant, two-phase commit protocol is the default mode. So it is sufficient for C/C++ master applications to call:
mco_HA_master_params_t MasterParams; mco_HA_master_params_init( &MasterParams ); mco_HA_set_master_params( db, &MasterParams );In C# and Java applications:
MasterConnection.Parameters MParams = new MasterConnection.Parameters(); con.SetReplicationMode( MParams );The eXtremeDB High Availability runtime does the initial synchronization in C/C++ master applications during the
mco_HA_attach_replica()
call and all other replication happens during the call tomco_trans_commit()
; in C# and Java applications during theMasterConnection.AttachReplica()
andMasterConnection.CommitTransaction()
method.On the replica side the eXtremeDB High Availability runtime manages initial replication for C/C++ applications within
mco_HA_attach_master()
. Whenmco_HA_attach_master()
is called, control is passed to the eXtremeDB High Availability runtime which manages the initial synchronization of the replica database and then waits for and processes transaction data sent from the master during the master call tomco_trans_commit()
. In C# and Java replica applications initial synchronization and subsequent transaction replication is managed by the eXtremeDB High Availability runtime during theReplicaConnection.AttachMaster()
method.
![]()
Implementation
Most C/C++ applications using eXtremeDB High Availability will employ just the following functions from the protocol layer API:
MCO_RET mco_HA_start(); void mco_HA_master_params_init(); MCO_RET mco_HA_set_master_params(); MCO_RET mco_HA_attach_replica(); void mco_HA_replica_params_init(); MCO_RET mco_HA_attach_master(); MCO_RET mco_HA_stop();Equivalently, most C# and Java applications using eXtremeDB High Availability will employ just the following API methods:
Database db = new Database(); db.Open(); MasterConnection con = new MasterConnection(db); con.SetReplicationMode(); con.AttachReplica(); con.StopReplication(); ReplicaConnection con = new ReplicaConnection(db); con.AttachMaster(); con.Disconnect(); db.Close();Using the HA “interface” API on the master side:
To initiate replication on the master side the application must:
- Initialize the HA runtime in C/C++ applications by calling
mco_HA_start()
; in C# and Java applications by instantiating a Database object with High Availability Support enabled, eg:Database db = new Database( new ExtremedbWrapper(),Database.Mode.HighAvailabilitySupport);
- In C/C++ applications, call
mco_HA_master_params_init()
to initialize themco_HA_master_params_t
structure (include/ha/mcoha.h
); in C# and Java applications instantiate aMasterConnection.Parameters
object.- Define the master mode and master flags in C/C++ applications by filling in the
mco_HA_master_params_t
structure. (Note that theMCO_MASTER_MODE
flag value must be set.); in C# and Java applications by setting the properties of theMasterConnection.Parameters
object.- Set up master replication mode flags in C/C++ applications by calling
mco_HA_set_master_params()
; in C# and Java applications by calling theMasterConnection.SetReplicationMode()
method.- Create a
listener
task.- In the listener thread, for C/C++ applications call
mco_HA_attach_replica()
; in C# and Java applications by call theMasterConnection.AttachReplica()
method.- To initiate asynchronous replication a couple of more steps are required (discussed later).
The following code fragment illustrates a simple C/C++ master implementation.
void* ListenToReplicas ( void *p ) { while ((! stop_flag ) { ret = mco_HA_attach_replica(...); if ( MCO_S_OK != ret ) // something went wrong, examine the return code ... else // replica is connected successfully } } int main(int argc, char* argv[]) { mco_HA_master_params_t MasterParams; … /* initialize HA subsystem */ mco_HA_start(); /* create the database */ rc = mco_db_open_dev( dbName, dbname_get_dictionary(),° dev, n_dev, &db_params); … /* connect to the database, obtain a database handle */ rc = mco_db_connect( dbName, &db ); … /* set MASTER mode */ mco_HA_master_params_init( &MasterParams ); mco_HA_set_master_params( db, &MasterParams ); /* create a ‘listener’ thread */ rc = pthread_create (&ConnThread, NULL, (void*)ListenToReplicas, &ha); /* Continue with the regular database processing */ while (master_has_some_work_to_do) { rc = mco_trans_start( db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t ); ... rc = mco_trans_commit(t); } /* Detach and close connections to replicas */ mco_HA_stop(db); }Note that
mco_HA_attach_replica()
is called in the context of a separate “listener” task. Upon receiving a connection request, this function performs the following actions to “activate” the replica:
- Wait for the replica connection
- Accept the connection, create a channel
- Transmit initial synchronization data to the replica
- Register the replica with the HA runtime
The
mco_HA_attach_replica()
function is described in detail in the API Reference section, but briefly its prototype is:mco_HA_attach_replica( mco_db_h db, char* masterport, timer_unit timeout);The timeout argument represents the “accept connection” timeout.
Note that If the master database is a shared-memory database and several processes access it, only one process (called the
primary
master) handles connections to replicas. So only the primary master process can call network-related functions such asmco_HA_keep_alive()
,mco_HA_attach_replica()
,etc.
A similar simple C# master implementation would look like the following:
public void Listen() { MasterConnection con = new MasterConnection(db); while (listening) { if (con.AttachReplica(PORT, ATTACH_TIMEOUT)) { // Replica connected… } } con.Disconnect(); } Master() { Database.Parameters parameters = new Database.Parameters(); db = new Database(new ExtremedbWrapper(), Database.Mode.HighAvailabilitySupport); db.Open( dbName, parameters, DATABASE_SIZE); MasterConnection con = new MasterConnection(db); // set HA mode MasterConnection.Parameters MParams = newMasterConnection.Parameters( MasterConnection.MCO_HAMODE_HOTSYNCH ); con.SetReplicationMode( MParams ); MParams.listening = true; // start listen thread Thread listenThread = new Thread(new ThreadStart(Listen)); listenThread.Start(); // continue with the regular database processing while (master_has_some_work_to_do) { con.StartTransaction(Database.Transaction.ReadWrite); ... con.CommitTransaction(); } // stop thread listening = false; listenThread.Join(); con.Disconnect(); db.Close(); }Using the HA “interface” API on the replica side:
To initiate replication on the replica-side the application must:
- Initialize the HA runtime in C/C++ applications by calling
mco_HA_start()
; in C# and Java applications by instantiating a Database object with High Availability Support enabled, eg:Database db = new Database( new ExtremedbWrapper(),Database.Mode.HighAvailabilitySupport);
- Create and connect to the database.
- Initialize the replica mode flags in C/C++ applications by calling
mco_HA_replica_params_init()
; in C# and Java applications by setting the properties of theReplicaConnection.Parameters
object.- Begin replication in C/C++ applications by calling
mco_HA_attach_master()
; in C# and Java applications by methodReplicaConnection.AttachMaster()
.The following code fragment illustrates a simple C/C++ replica implementation.
int main(int argc, char* argv[]) { int stopReason = 0; mco_HA_replica_params_t ReplicaParams; ... /* initialize HA subsystem */ mco_HA_start(); /* create the database */ rc = mco_db_open_dev( dbName, dbname_get_dictionary(),° dev, n_dev, &db_params); … /* connect to the database, obtain a database handle */ rc = mco_db_connect( dbName, &db ); … /* set replica params */ mco_HA_replica_params_init( &ReplicaParams ); rc = mco_HA_attach_master( &db, mastername, &ReplicaParams, &stopReason, TM_CONNECTION_TIMEOUT); return stopReason; }Note that
mco_HA_attach_master()
is a blocking call. Essentially all control is turned over at this point to the eXtremeDB High Availability runtime which manages the initial synchronization and then commits transactions sent from the master. The function is described in detail in the API Reference section, but briefly its prototype is:MCO_RET mco_HA_attach_master( mco_db_h db, const char* conn_string, const mco_HA_replica_params_t* params, MCO_E_HA_REPLICA_STOP_REASON* stop_reason, timer_unit timeout);The
stop_reason
indicates why the runtime has returned control to the application (include/ha/mcoha.h
). When control is returned to the replica application, it should examine thestop_reason
and make a decision on the course of further action. It could, for example, become the master application itself, or simply terminate. The timeout represents theconnection
timeout (the period of time the replica waits while attempting to make a connection to the master). Theparams
structure contains a set of replica control flags (include/ha/mcoha.h
). For exampleMCO_HAMODE_REPLICA_NOTIFICATION
, etc.A similar simple C# replica implementation would look like the following:
public Slave() { Database.Parameters parameters = new Database.Parameters(); parameters.MemPageSize = PAGE_SIZE; db = new Database(new ExtremedbWrapper(), Database.Mode.HighAvailabilitySupport); db.Open( dbName, parameters, DATABASE_SIZE ); // start working thread running = true; Thread inspectThread = new Thread(new ThreadStart(Run)); inspectThread.Start(); ReplicaConnection con = new ReplicaConnection(db); ReplicaConnection.Parameters RParams = new ReplicaConnection.Parameters(); if (!con.AttachMaster("localhost:" + PORT, replParams, CONNECT_TIMEOUT)) { Console.WriteLine("Failed to connect to master"); } //stop working thread running = false; inspectThread.Join(); Console.WriteLine("Replica is terminated"); con.Disconnect(); db.Close(); }