MySQL::Replication is a Perl replacement for MySQL's built-in replication. The reason for this module is that there are a number of issues with MySQL's built-in replication:
- You Can't Have Multiple Masters
By design, slaves can only replicate from a single master. Emulating multi-master replication is possible, but this creates even further issues:
- There Is A Possibility Of Infinite Replication Loops
Emulating multi-master replication with a ring topology depends on having all masters in the ring being available. If a master dies while still having its queries circulating around the ring, the queries won't be filtered out and so an infinite replication loop occurs.
Although a ring topology can be created with MySQL::Replication, there is no ring replication. This is because clients do not binlog when executing replicated queries. So when a server is serving out local binlogs, there is no risk of serving non-locally generated queries and thus no risk of infinite replication loops.
- Time Is Wasted By Time Slicing
Emulating multi-master replication by time slicing wastes time when the currently connected master doesn't have anything to replicate.
Since MySQL::Replication achieves multi-master replication by running multiple instances of the client in parallel, there is no time slicing via a timer and thus no time wasted by time slicing. Note that time slicing still happens via the operating system's process scheduler however since socket reads in the client are blocking, there is no time wasted by polling.
- Queries May Get Replayed After A Slave Crash
A slave's master position is recorded in the relay-log.info file however writes to the InnoDB tablespace and relay-log.info are not atomically synced to disk. If a slave dies and comes back online, files may be in an inconsistent state. If the InnoDB tablespace was flushed to disk before the crash but relay-log.info wasn't, the slave will restart replication from a stale position and so will replay queries.
MySQL::Replication clients store their server positions inside the InnoDB tablespace (i.e. the Replication.SourcePosition table by default). Since updates are done within the same transaction as replicated queries are executed in, writes are atomic. If a slave dies and comes back online, we will still be in a consistent state since either the transaction was committed or it will be rolled back.
- Moving Slaves To Different Masters Is Hard
A slave's master position is relative to the directly connected master's binlogs. Given a multi-layer replication topology e.g. a tree topology, a slave's master position is still relative to the directly connected master's binlogs and not relative to the root master's binlogs. If a master in a middle layer dies, moving its slaves to a different master is non-trivial since they will all need their master positions translated to the new master's binlogs.
MySQL::Replication always deals with canonical binlog positions. In a multi-layer replication topology e.g. a tree topology, positions are always relative to the root server's binlogs. If a relay in a middle layer dies, moving its clients to a different relay is a simple configuration item change since no translation is needed.