{"id":22513414,"url":"https://github.com/emahtab/mysql-master-master-replication","last_synced_at":"2025-07-07T00:31:37.718Z","repository":{"id":266842343,"uuid":"899521608","full_name":"eMahtab/mysql-master-master-replication","owner":"eMahtab","description":"A demo showing bidirectional database replication between two MySQL master.","archived":false,"fork":false,"pushed_at":"2024-12-06T16:54:27.000Z","size":918,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-02T03:19:08.057Z","etag":null,"topics":["database-replication","master-master-replication","mysql"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eMahtab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-06T12:46:28.000Z","updated_at":"2024-12-06T16:54:30.000Z","dependencies_parsed_at":"2024-12-06T13:57:16.446Z","dependency_job_id":"6af2f38b-474b-4c04-9888-c4aa9be28da4","html_url":"https://github.com/eMahtab/mysql-master-master-replication","commit_stats":null,"previous_names":["emahtab/mysql-master-master-replication"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eMahtab%2Fmysql-master-master-replication","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eMahtab%2Fmysql-master-master-replication/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eMahtab%2Fmysql-master-master-replication/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eMahtab%2Fmysql-master-master-replication/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eMahtab","download_url":"https://codeload.github.com/eMahtab/mysql-master-master-replication/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245950629,"owners_count":20699099,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database-replication","master-master-replication","mysql"],"created_at":"2024-12-07T03:12:17.371Z","updated_at":"2025-03-28T01:23:13.202Z","avatar_url":"https://github.com/eMahtab.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# MySQL Bidirectional database replication between two master (master-master-replication)\n\nThis demo is a variation of https://github.com/eMahtab/mysql-master-slave-replication , where we had setup Master Slave replication from a single mysql master to a single mysql slave/replica.\n\nIn this demo we setup two MySQL instances (e.g. mysql-master-1 and mysql-master-2), both working as master. \n**mysql-master-1 replicates its data to mysql-master-2 and mysql-master-2 replicates its data to mysql-master-1.**\n\n### !!! Prerequisite : You would need Docker installed on your system to follow along this demo.\n\nWe would run both mysql-master-1 and mysql-master-2 as docker containers, using docker compose.\n\n## Step 1 : Create the Docker compose file and execute docker compose up\n\nBelow docker-compose-master-master.yml declares two services, named as mysql_master_1 and mysql_master_2 (in docker compose file actual containers are named as mysql-master-1 and mysql-master-2). We are using **mysql:8.0** as the docker image, and declare root user password as `toor` and create a test database.\n\n**Make sure docker engine is running on your host machine before running the `docker compose -f docker-compose-master-master.yml up` command.**\n\n```yml\n---\nversion: \"2\"\nservices:\n  mysql_master_1:\n    image: mysql:8.0\n    container_name: mysql-master-1\n    volumes:\n      - mysql-master-1-volume:/tmp\n    command:\n      [\n        \"mysqld\",\n        \"--datadir=/tmp/master1/data\",\n        \"--log-bin=bin.log\",\n        \"--server-id=1\"\n      ]\n    environment:\n      \u0026mysql-default-environment\n      MYSQL_ROOT_PASSWORD: toor\n      MYSQL_DATABASE: test\n      MYSQL_USER: test_user\n      MYSQL_PASSWORD: insecure\n    ports:\n      - \"3308:3306\"\n\n  mysql_master_2:\n    image: mysql:8.0\n    container_name: mysql-master-2\n    volumes:\n      - mysql-master-2-volume:/tmp\n    command:\n      [\n        \"mysqld\",\n        \"--datadir=/tmp/master2/data\",\n        \"--log-bin=bin.log\",\n        \"--server-id=2\"\n      ]\n    environment: *mysql-default-environment\n    ports:\n      - \"3309:3306\"\n\nvolumes:\n  mysql-master-1-volume:\n  mysql-master-2-volume:\n```\n\n![\"Starting two MySQL Instances as Docker Containers\"](docker-compose-up.png?raw=true)\n\n![\"Two MySQL Instances as Docker Containers\"](docker-containers.png?raw=true)\n\n## Step 2 : Create Replication user on both the MySQL instances with REPLICATION SLAVE privilege\nNext we need to create a replication user on both the MySQL instances `(mysql-master-1 and mysql-master-2)` and grant that user `REPLICATION SLAVE` privilege.\nTo do this, we first open the bash shell on each MySQL instance **`docker exec -it mysql-master-1 bash`** and connect to mysql **`mysql -uroot -ptoor`** running on the instance, then execute below mysql commands.\n```sql\nCREATE USER 'replicator'@'%' IDENTIFIED BY 'rotacilper';\nGRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';\nFLUSH PRIVILEGES;\n```\nHere we create a replication user called `replicator` with password `rotacilper` and grant this user **`REPLICATION SLAVE`** privilege, and finally flush privileges.\n\n## Step 3 : Execute SHOW MASTER STATUS on both the MySQL instances\nGet the master status, execute the command **`SHOW MASTER STATUS;`** on both the MySQL instances to find the Binlog file and position.\n\n![\"Get Master status\"](create-replication-user-and-show-status.png?raw=true)\n\n![\"Get Master status\"](create-replication-user-and-show-status-2.png?raw=true)\n\n## Step 4 : Execute `CHANGE MASTER TO` and `START SLAVE;` command on both the MySQL instances\nNext we need to execute **`CHANGE MASTER TO`** and `START SLAVE;` command on both the MySQL instances. Connect to each MySQL instance and execute below command, **_don't forget to update MASTER_LOG_FILE and MASTER_LOG_POS values_** which you got from executing SHOW MASTER STATUS command.\n\n### On mysql-master-1\nUpdate **_MASTER_LOG_FILE and MASTER_LOG_POS_** and then execute this on MySQL instance running on mysql-master-1 docker container\n\n```sql\nCHANGE MASTER TO\n  MASTER_HOST='mysql_master_2',\n  MASTER_PORT=3306,\n  MASTER_USER='replicator',\n  MASTER_PASSWORD='rotacilper',\n  MASTER_LOG_FILE='[log_file_name_from_mysql-master-2]',\n  MASTER_LOG_POS=[log_position_from_mysql-master-2],\n  GET_MASTER_PUBLIC_KEY=1;\n```\n\nand then\n\n```sql\nSTART SLAVE;\n```\n\n### On mysql-master-2\nUpdate **_MASTER_LOG_FILE and MASTER_LOG_POS_** and then execute this on MySQL instance running on mysql-master-2 docker container\n\n```sql\nCHANGE MASTER TO\n  MASTER_HOST='mysql_master_1',\n  MASTER_PORT=3306,\n  MASTER_USER='replicator',\n  MASTER_PASSWORD='rotacilper',\n  MASTER_LOG_FILE='[log_file_name_from_mysql-master-1]',\n  MASTER_LOG_POS=[log_position_from_mysql-master-1],\n  GET_MASTER_PUBLIC_KEY=1;\n```\n\nand then\n\n```sql\nSTART SLAVE;\n```\n\n![\"CHANGE MASTER TO\"](change-master-to-and-start.png?raw=true)\n\n![\"CHANGE MASTER TO\"](change-master-to-and-start-2.png?raw=true)\n\n## Step 5 : Insert Records on mysql-master-1 and see Replication in action\nBy performing the steps 1 to 4, we have set the replication from mysql-master-1 to mysql-master-2 and vice versa, now whatever changes are done on any one of the MySQL instance will be replicated to other MySQL instance automatically. \n\nWe create a `users` table under test database on `mysql-master-1` and insert 20 records in `users` table\n\n```sql\nUSE test\nCREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL);\nINSERT INTO users (name)\nVALUES\n    ('Alice'),\n    ('Bob'),\n    ('Charlie'),\n    ('David'),\n    ('Eve'),\n    ('Frank'),\n    ('Grace'),\n    ('Hannah'),\n    ('Ivy'),\n    ('Jack'),\n    ('Karen'),\n    ('Liam'),\n    ('Mia'),\n    ('Noah'),\n    ('Olivia'),\n    ('Paul'),\n    ('Quincy'),\n    ('Rachel'),\n    ('Sophia'),\n    ('Thomas');\n```\n![\"Add Records on mysql instance\"](add-records.png?raw=true)\n\nRecords are replicated on **_mysql-master-2_**\n\n![\"Records are replicated to other mysql instance\"](check-records-on-other-mysql-instance.png?raw=true)\n\n## Step 5a : Create and execute a MySQL procedure on mysql-master-1 and see Replication in action\n\n```sql\nDELIMITER $$\n```\nNext we create a procedure `insert_users` which inserts 10,000 records in `users` table\n```sql\nCREATE PROCEDURE insert_users()\nBEGIN\n    DECLARE i INT DEFAULT 1;\n    WHILE i \u003c= 10000 DO\n        INSERT INTO users (name) VALUES (CONCAT('User_', i));\n        SET i = i + 1;\n    END WHILE;\nEND$$\n```\n```sql\nDELIMITER ;\n```\n\n### And then execute the procedure\n\n```sql\nCALL insert_users();\n```\n\n![\"Create and execute procedure on mysql-master-1\"](create-and-execute-procedure.png?raw=true)\n\n### Below screenshot shows replication in progress and after some time all 10,000 records are replicated on mysql-master-2 \n\n![\"10,000 Records replicated on other MySQL instance\"](records-replicated-on-other-master.png?raw=true)\n\n## Step 6 : Testing the replication in opposite direction, from mysql-master-2 to mysql-master-1 (Bidirectional data replication)\n\nWe insert 2 records in `users` table on mysql-master-2 , and those 2 records are replicated to mysql-master-1, as shown in screenshot below.\n\n![\"Bidirectional data replication\"](bidirectional-data-replication.png?raw=true)\n\n### Step 6a : Testing the replication in opposite direction, from mysql-master-2 to mysql-master-1 (Bidirectional data replication)\nNext we create a table `da_events` on `mysql-master-2` and insert a single record in the table.\n```sql\nCREATE TABLE da_events (id INT AUTO_INCREMENT PRIMARY KEY, event_type VARCHAR(200));\n\nINSERT INTO da_events VALUES (1, 'FETCH_CATEGORY');\n```\nAs we can see from screenshot the data is replicated on `mysql-master-1`\n\n![\"Bidirectional data replication\"](bidirectional-data-replication-2.png?raw=true)\n\n# References :\n1. https://github.com/eMahtab/mysql-master-slave-replication\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femahtab%2Fmysql-master-master-replication","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femahtab%2Fmysql-master-master-replication","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femahtab%2Fmysql-master-master-replication/lists"}