NDB Cluster Replication Conflict Resolution to determine whether changes originating on the replica are concurrent with any changes that originate locally, and are therefore potentially in conflict. Most of what follows in the description of  NDB$EPOCH()  also applies to  NDB$EPOCH_TRANS() . Any exceptions are noted in the text. NDB$EPOCH()  is asymmetric, operating on one NDB Cluster in a bidirectional replication configuration (sometimes referred to as “active-active”  replication). We refer here to cluster on which it operates as the primary, and the other as the secondary. The replica on the primary is responsible for detecting and handling conflicts, while the replica on the secondary is not involved in any conflict detection or handling. When the replica on the primary detects conflicts, it injects events into its own binary log to compensate for these; this ensures that the secondary NDB Cluster eventually realigns itself with the primary and so keeps the primary and secondary from diverging. This compensation and realignment mechanism requires that the primary NDB Cluster always wins any conflicts with the secondary—that is, that the primary’s changes are always used rather than those from the secondary in event of a conflict. This “primary always wins”  rule has the following implications: NDB$EPOCH()  and  NDB$EPOCH_TRANS()  do not require any user schema modifications, or application changes to provide conflict detection. However, careful thought must be given to the schema used, and the access patterns used, to verify that the complete system behaves within specified limits. Each of the  NDB$EPOCH()  and  NDB$EPOCH_TRANS()  functions can take an optional parameter; this is the number of bits to use to represent the lower 32 bits of the epoch, and should be set to no less than the value calculated as shown here: For the default values of these configuration parameters (2000 and 100 milliseconds, respectively), this gives a value of 5 bits, so the default value (6) should be sufficient, unless other values are used for TimeBetweenGlobalCheckpoints ,  TimeBetweenEpochs , or both. A value that is too small can result in false positives, while one that is too large could lead to excessive wasted space in the database. Both  NDB$EPOCH()  and  NDB$EPOCH_TRANS()  insert entries for conflicting rows into the relevant exceptions tables, provided that these tables have been defined according to the same exceptions table schema rules as described elsewhere in this section (see NDB$OLD(column_name)). You must create any exceptions table before creating the data table with which it is to be used. As with the other conflict detection functions discussed in this section,  NDB$EPOCH()  and  NDB $EPOCH_TRANS()  are activated by including relevant entries in the  mysql.ndb_replication  table 4645 CEIL( LOG2( TimeBetweenGlobalCheckpoints / TimeBetweenEpochs ), 1) •Operations that change data, once committed on the primary, are fully persistent and are not undone or rolled back by conflict detection and resolution. •Data read from the primary is fully consistent. Any changes committed on the Primary (locally or from the replica) are not reverted later. •Operations that change data on the secondary may later be reverted if the primary determines that they are in conflict. •Individual rows read on the secondary are self-consistent at all times, each row always reflecting either a state committed by the secondary, or one committed by the primary. •Sets of rows read on the secondary may not necessarily be consistent at a given single point in time. For NDB$EPOCH_TRANS() , this is a transient state; for  NDB$EPOCH() , it can be a persistent state. •Assuming a period of sufficient length without any conflicts, all data on the secondary NDB Cluster (eventually) becomes consistent with the primary’s data.