Is it possible to set-up MySql Replication to have one slave listening to two different masters?
5 Answers
By design, one mysqld process cannot simultaneously listen to two different Masters.
The CHANGE MASTER TO command only allows you to set one Master as a source to read.
In order to emulate this, you would have to alternate between the two Masters programmatically. How do you do that ?
Here is the basic idea
- Master M1
- Master M2
- Slave S1
Setup Replication of M1 to S1 and then M2 to S1 like this
- 1) Have S1 run CHANGE MASTER TO with M1 as the Source
- 2) START SLAVE;
- 3) Run Replication for a Little While
- 4) STOP SLAVE;
- 5) Have S1 run CHANGE MASTER TO with M2 as the Source
- 6) START SLAVE;
- 7) Run Replication for a Little While
- 8) STOP SLAVE;
- 9) Go Back to Step 1
Each time you switch from one Master to another, you must record two values from SHOW SLAVE STATUS\G
- Relay_Master_Log_file
- Exec_Master_Log_Pos
These two values represent the last SQL Statement that came from the Master and was is next to be executed on the Slave.
There is one major caution : As long as M1 and M2 are updating mutually exclusive databases, this algorithm should be just fine.
-
Although I haven't really needed it myself yet, I have been thinking about this issue earlier. Wouldn't it be possible to basically pipe the binlog of the second master into the mysql slave? I guess the best thing would be to have a tool that also keeps an eye on the results of each query and stops on an error just like the normal replication-slave thread does. But in essence a simple pipe should do too. Of course both masters writing to the same database/table would become tricky quickly. Something for you gurus to ponder about?– JannesCommented Feb 6, 2012 at 10:35
-
1I think it's worth adding to your answer that even though MySQL 5.6 doesn't do this, that 5.7 will support multiple masters. Commented Jul 2, 2014 at 9:04
Rolando's solution has many caveats. The first being one replica stream is necessarily not replicating while the other works. This is going to give you periods of time where your slave is out of synch. You now have to play a delicate balancing act to ensure each has enough time to catch up when it has its "turn".
As described you also have to play book keeper of log positions to switch back to. This really just seems buggy, opening the window for missing or inconsistent data or even breaking replication when it goes wrong (either being caused by even a just 'off by one' error in the log position)
I would recommend just running multiple mysql instances. There's nothing stopping you from running two or more mysql's on the same machine. They cannot both operate on the same port of course. I don't really see this as being a problem though as every client and library allows you to specify something other than 3306.
Just specify port=3307 (or whatever in one of the .cnf files).
You will also want to take care in ensuring the individually configured buffer pools and other memory configurations aren't at odds with each other. This is actually a benefit though as you can more finely tune those settings to the specific requirements of the individual databases that are being replicated.
This way you just have two replication streams running into the same server; never behind, no book keeping required, no "swapping" script required.
-
I am glad somebody understands the bookkeeping madness. Nice answer as well. +1 !!! Commented Feb 3, 2012 at 17:20
Fan in (multi-source replication) will be supported from MySQL 5.7.
A labs release is available here: http://labs.mysql.com/
MariaDB which can be used as inplace replacement for MySql can be used. It supports it from version 10.2
The problem with Mysql 5.7 support is the need for GTID , meaning that master MUST be also changed , in case of MariaDb this is not the case.
Example/HowTo link: http://www.skysql.com/blogs/dean-ellis/multi-source-replication-mariadb-100
Replication with One slave and Two master: Yes! we can do it by creating channels in slaves. Below are the steps to do it using GTID
Following are the steps
masters
- 192.168.0.201:3307
- 192.168.0.201:3308
slave
- 192.168.0.209:3306
On Master
- Check GTID is ON: SHOW VARIABLES LIKE 'gtid_mode';
- Create a replication user on the master: CREATE USER 'replication_user'@'192.168.0.209' IDENTIFIED WITH mysql_native_password BY 'password';
- Grant replication privileges to the user: GRANT REPLICATION SLAVE ON . TO 'replication_user'@'192.168.0.209'; FLUSH PRIVILEGES;
- Show the master status: SHOW MASTER STATUS\G;
On Slave
- Check GTID is ON:
SHOW VARIABLES LIKE 'gtid_mode';
- Stop and reset the slave on the slave server:
STOP REPLICA FOR CHANNEL "DEVELOPMENT";
RESET REPLICA FOR CHANNEL "DEVELOPMENT";
Add GTID on the slave for channel DEVELOPMENT:
SET GLOBAL gtid_purged='ccb0d141-dc54-11ee-923c-0242c0a8b005:1-33'; <!--- Should be same as master 192.168.0.201:3307 --->
Change the master settings on the slave for channel DEVELOPMENT:
CHANGE REPLICATION SOURCE TO SOURCE_HOST='192.168.0.201', SOURCE_PORT=3307, SOURCE_USER='replication_user', SOURCE_PASSWORD='password', SOURCE_AUTO_POSITION=1 FOR CHANNEL "DEVELOPMENT";
Start the slave for the specified channel:
START REPLICA FOR CHANNEL "DEVELOPMENT";
Show the slave status for the specified channel:
SHOW REPLICA STATUS FOR CHANNEL "DEVELOPMENT"\G;
Add GTID on the slave for channel PRODUCTION:
SET GLOBAL gtid_purged='180c0583-e1e0-11ee-84fa-0242c0a84003:1-107'; <!--- Should be same as master 192.168.0.201:3308 --->
Change the master settings on the slave for channel PRODUCTION:
CHANGE REPLICATION SOURCE TO SOURCE_HOST='192.168.0.201', SOURCE_PORT=3308, SOURCE_USER='replication_user', SOURCE_PASSWORD='password', SOURCE_AUTO_POSITION=1 FOR CHANNEL "PRODUCTION";
Start the slave for the specified channel:
START REPLICA FOR CHANNEL "PRODUCTION";
Show the slave status for the specified channel: ````SHOW REPLICA STATUS FOR CHANNEL "PRODUCTION"\G;```
Reference: https://www.svastikkka.com/2024/03/mysql-multi-source-master-slave.html