# Synchronization Modes

> For eXtremeDB High Availability applications there are two orthogonal operations to be aware of: initial synchronization and transaction replication. The initial synchronization is performed once after the replica has attached and can be static (the default) or hot-sync. These initial synchronization modes are described in detail below. It is important to note that static initialization blocks the application's write transactions on the master, while hot-sync allows `READ_WRITE` transactions during initialization.

> The transaction replication can be synchronous or asynchronous. In synchronous replication mode the master waits for acknowledgment (ack) from the replicas for each transaction and thus a transaction commit on the master returns only after the changes were applied to the replica's database. In asynchronous replication mode the master puts serialized transactions to the asynchronous buffer and sends them later. (The asynchronous buffer is processed in a thread different from the one that created the database connection. So here “later” means that the transaction is sent to the network “after” the commit call has returned control to the database thread. The exact time at which the transaction is sent to the network is not known and is outside the control of the database runtime.)

> ## Static Synchronization

> Static Synchronization (illustrated below) is the default means of initializing a newly attached replica. In this mode, the master database begins a read-only transaction, which causes any read-write transactions to be queued until the initial synchronization is completed. (When using the MURSIW Transaction Manager, other read-only transactions can execute in parallel with the initial synchronization, but only if they are started before all read-write transactions, or started with a higher priority - a read-only transaction started at the same priority and after a read-write transaction will enter the queue after the read-write transaction and will wait for the read-write transaction’s completion. For a more detailed explanation of Transaction Manager behavior see the eXtremeDB User Guide.) This is the fastest synchronization mode and the default means of initializing a newly attached replica. Note that the database runtime initializes and performs the synchronization on its own – no action from the application is necessary.

> Static synchronization is the default mode, so in C/C++ applications it is sufficient to call function `mco_HA_master_params_init()` to initialize the synchronization mode. In C# and Java applications the default constructor for `MasterConnection.Parameters` sets the default static synchronization mode.

> ## “Hot” Synchronization

> If a database is very large, the communication channel is slow, or the target system at the master or replica are slow, static synchronization can make the master database unavailable for read-write transactions for too long. These conditions are the case for hot synchronization (illustrated below). In this mode, the master database may still be updated during the initial synchronization. Initial synchronization will take longer because data that is modified after initial synchronization started but before it completed will have to be retransmitted, and because the master database system is simply busier. Similarly, database response times will be somewhat degraded because the database run-time is also busy with the initial synchronization. Also asynchronous replication mode is temporarily turned off while the initial synchronization completes.

> Hot synchronization is enabled in C/C++ master applications by setting the `mode_flags` element to `MCO_HAMODE_HOTSYNCH` in the master:

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

> In C# and Java master applications the `MasterConnection.Parameters` constructor is invoked with the `MasterConnection.MCO_HAMODE_HOTSYNC` flag:

>         MasterConnection.Parameters MParams = new MasterConnection.Parameters(
>         MasterConnection.MCO_HAMODE_HOTSYNCH );
>         con.SetReplicationMode( MParams );

> ### Combining Asynchronous Replication and Hot Synchronization

> If the application uses both hot-sync initial synchronization and asynchronous replication, then the transaction replication will be asynchronous except during time intervals when a newly attached replica is initialized. In other words, during the initial synchronization of a newly attached replica the replication is temporarily switched to synchronous mode.

> To combine asynchronous replication with hot-sync initial synchronization in C/C++ master applications, set both flags as follows:

>         MasterParams.mode_flags = MCO_MASTER_MODE | MCO_HAMODE_HOTSYNCH | MCO_HAMODE_ASYNCH;

> In C# and Java master applications:

>         MasterConnection.Parameters MParams = new MasterConnection.Parameters(
>             MasterConnection.MCO_HAMODE_HOTSYNCH |
>             MasterConnection.MCO_HAMODE_ASYNCH );

> ## Binary Schema Evolution

> In order to maintain availability of the system during upgrades of the application, eXtremeDB High Availability supports binary schema evolution. In this mode, the eXtremeDB High Availability runtime automatically converts objects from the master schema to the replica's schema. When the replica receives a copy of the master’s database, the initial synchronization step can accommodate the presence of new classes, new fields, new indexes, dropped classes, dropped fields, dropped indexes, changes to indexes, and changes to fields as long as the change does not cause loss of precision.

> Synchronization with binary schema evolution is enabled in C/C++ master applications by setting the `mode_flags` element to `MCO_HAMODE_BINEVOLUTION` in the master:

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

> In C# and Java master applications the MasterConnection.Parameters constructor is invoked with the `MasterConnection.MCO_HAMODE_BINEVOLUTION` flag:

>         MasterConnection.Parameters MParams = new MasterConnection.Parameters(
>         MasterConnection.MCO_HAMODE_BINEVOLUTION );
>         con.SetReplicationMode( MParams );

> In general, the process of porting an online database to a new schema is as follows:

> - Build the new version of the replica application, with the updated schema
> - Install the new replica application
> - Start the new replica
> - In the C/C++ replica, upon return from `mco_HA_attach_master()`, call `mco_HA_set_master_params()`, in C# and Java replicas when returning from method `ReplicaConnection.AttachMaster()` instantiate a `MasterConnection()`, to become the new master.
> - Stop the old master
> - If any other replicas exist, they reconnect to the new master
> - One by one, update the old master application and any other replicas.
> - If desired, when the updated old master application is restarted, it can become master once again
> - In this manner, there is always a master application executing and maintaining system availability.

> The replication process with `BSE` is illustrated in the following diagram:

> ### Example

> The C SDK sample Binenv demonstrates how the `MCO_HAMODE_BINEVOLUTION` mode flag turns binary schema evolution ON to automatically convert objects from the master schema to the replica's schema. The Java SDK sample habinenv demonstrates the same using the connection parameters `MasterConnection.MCO_HAMODE_BINEVOLUTION.`

> ## Stateful Replication

> Normally, when a replica attaches to a master, it receives a copy of the master’s entire database through the initial synchronization step (either static or hot). This can take a relatively long time. With “stateful” replication enabled, the master runtime retains a number of transactions (specified by the application and depending on available system memory) in a circular buffer in addition to transmitting them to replicas. When synchronization is required, the master transmits only the buffer, not the entire database.

> For example, a brief interruption in the communication channel may cause a few transactions to be missed by a replica between the time that it was disconnected by the network and when it is able to reconnect. When the replica reconnects, if the missed transactions are in the master’s buffer, the initial synchronization step can be bypassed in favor of re-transmitting (replicating) just the missed transactions. This is termed `stateful` replication because the master is informed of the state of the replica’s database when the replica requests to attach to the master.

> Synchronization with stateful replication is enabled in C/C++ master applications by setting the `mode_flags` element to `MCO_HAMODE_STATEFUL_REPLICATION` in the master:

>         mco_HA_master_params_t MasterParams;
>         mco_HA_master_params_init( &MasterParams );
>         MasterParams.mode_flags = MCO_MASTER_MODE | MCO_HAMODE_STATEFUL_REPLICATION;
>         MasterParams.trans_log_length = 25;
>         …
>         mco_HA_set_master_params( db, &MasterParams );

> Note that the size of the circular transaction buffer is determined by specifying the value of `MasterParams.trans_log_length = value`.

> In C# and Java master applications the `MasterConnection.Parameters` constructor is invoked with the `MasterConnection.MCO_HAMODE_STATEFUL_REPLICATION` flag:

>         MasterConnection.Parameters MParams = new MasterConnection.Parameters(
>                                     MasterConnection.MCO_HAMODE_STATEFUL_REPLICATION );
>         con.SetReplicationMode( MParams );