Business Requirement
Both the source and target schemas on the same MySQL instance contain a table named student. Any INSERT, UPDATE, or DELETE executed against source.student must be reflected in target.student with sub-second latency.
Candidate Approaches
1. Shell Script
Quick PoC with bash + mysqldump was abandoned because the team lacked shell expertise and the approach would only support batch, not real-time, synchronization.
2. DataX
Alibaba’s offline batch tool supports heterogeneous sources, but:
- Distribution size ≈ 771 MB
- Requires Python runtime
- Designed for cross-DB engines, overkill for two schemas in the same MySQL instance
3. Otter – Chosen Solution
Otter is a Java-based, distributed, near-real-time replication system that leverages Canal for binlog parsing and ZooKeeper for cluster coordination.
3.1 Architecture Overveiw
- Canal tails the MySQL binary log and publishes row events.
- Otter Manager (web console) pushes channel definitions to Node(s).
- Each Node applies the captured events to the destination schema and reports progress back to Manager.
- ZooKeeper keeps Manager and Nodes in sync, enabling horizontal scaling.
Environment Specification
| Component | Version |
|---|---|
| MySQL | 5.7.td> |
| JDK | 1.8 |
| Otter Manager | 4.2.17 |
| Otter Node | 4.2.17 |
| ZooKeeper | 3.4.10 |
| Aria2 (for media download) | 1.34.0 |
Setup Steps
1. Enable Binary Logging
Add the following to my.cnf (Linux) or my.ini (Windows, saved as GB2312):
[mysqld]
log-bin=/var/lib/mysql/mysql-bin
binlog-format=ROW
server-id=201609 # unique across the topology
Verify with:
SHOW MASTER STATUS;
2. Prepare Otter System Tables
Import otter-manager-schema.sql. If you hit
ERROR 1067 (42000): Invalid default value for 'GMT_CREATE'
set explicit defaults:
ALTER TABLE `otter_system`.`ALARM_RULE`
MODIFY `GMT_CREATE` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP;
3. Configure ZooKeeper
# conf/zoo.cfg
tickTime=2000
dataDir=/opt/zookeeper/data
clientPort=2181
4. Configure Otter Manager
# conf/otter.properties
otter.domainName = 127.0.0.1
otter.port = 8080
otter.database.driver = com.mysql.jdbc.Driver
otter.database.url = jdbc:mysql://127.0.0.1:3306/otter_system
otter.database.username = otter
otter.database.password = otter_pwd
5. Register Node
# conf/otter.properties on each node
otter.nodeId = 1
otter.manager.address = 127.0.0.1:1099
Define a Channel in Manager UI
- Create two Data Sources pointing to the same MySQL instance but different schemas.
- Create a Data Media Pair mapping
source.student→target.student. - Enible row mode and field overwrite if you want identical replicas.
- Start the channel; initial load plus streaming replication begins immediately.
Common Pitfalls
- Duplicate server-id prevents MySQL startup.
- Wrong binlog format (STATEMENT) causes Otter to miss row images.
- Missing time-zone tables in MySQL leads to timestamp drift warnings.