NDB Cluster Replication Conflict Resolution well. This is accomplished by reflecting any operation successfully applied on and replicated from the secondary back to the secondary. On its return to the secondary, it can be used to reapply an operation on the secondary which was deleted by an operation originating from the primary. When using  NDB$EPOCH2() , you should keep in mind that the secondary applies the delete from the primary, removing the new row until it is restored by a reflected operation. In theory, the subsequent insert or update on the secondary conflicts with the delete from the primary, but in this case, we choose to ignore this and allow the secondary to “win” , in the interest of preventing divergence between the clusters. In other words, after a delete, the primary does not detect conflicts, and instead adopts the secondary’s following changes immediately. Because of this, the secondary’s state can revisit multiple previous committed states as it progresses to a final (stable) state, and some of these may be visible. You should also be aware that reflecting all operations from the secondary back to the primary increases the size of the primary’s logbinary log, as well as demands on bandwidth, CPU usage, and disk I/O. Application of reflected operations on the secondary depends on the state of the target row on the secondary. Whether or not reflected changes are applied on the secondary can be tracked by checking the  Ndb_conflict_reflected_op_prepare_count and  Ndb_conflict_reflected_op_discard_count  status variables. The number of changes applied is simply the difference between these two values (note that Ndb_conflict_reflected_op_prepare_count  is always greater than or equal to Ndb_conflict_reflected_op_discard_count ). Events are applied if and only if both of the following conditions are true: If both of these conditions are not met, the reflected operation is discarded by the secondary. Limitations on NDB$EPOCH().  The following limitations currently apply when using  NDB$EPOCH()  to perform conflict detection: Deletes should be externally serialized, or routed to one cluster only. Alternatively, a separate row should be updated transactionally with such deletes and any inserts that follow them, so that conflicts can be tracked across row deletes. This may require changes in applications. 4647 •Conflicts between delete operations may result in divergence between the primary and secondary. When a row is deleted on both clusters concurrently, the conflict can be detected, but is not recorded, since the row is deleted. This means that further conflicts during the propagation of any subsequent realignment operations are not detected, which can lead to divergence. •Additional storage is required for tables using the  NDB$EPOCH()  and  NDB$EPOCH_TRANS()  functions; from 1 to 32 bits extra space per row is required, depending on the value passed to the function. •Conflicts are detected using NDB Cluster epoch boundaries, with granularity proportional to TimeBetweenEpochs  (default: 100 milliseconds). The minimum conflict window is the minimum time during which concurrent updates to the same data on both clusters always report a conflict. This is always a nonzero length of time, and is roughly proportional to  2 * (latency + queueing + TimeBetweenEpochs) . This implies that—assuming the default for  TimeBetweenEpochs  and ignoring any latency between clusters (as well as any queuing delays)—the minimum conflict window size is approximately 200 milliseconds. This minimum window should be considered when looking at expected application “race”  patterns. •The row was last modified by the primary. It is possible that the modification was accomplished through the execution of a reflected operation. •The existence of the row—that is, whether or not it exists—is in accordance with the type of event. For delete and update operations, the row must already exist. For insert operations, the row must  not  exist.