commit 3de1538f07fd7cfa0674d89919ecd14a6b9d8744 Author: Vladyslav Babak Date: Mon Nov 13 23:43:21 2017 +0200 mysql master-slave replication setup diff --git a/.env b/.env new file mode 100644 index 0000000..b753bf2 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +# default environment variables https://docs.docker.com/compose/env-file/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c0f72fe --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +.idea +data diff --git a/README.md b/README.md new file mode 100644 index 0000000..98927dc --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +Docker MySQL master-slave replication +======================== + +MySQL master-slave replication with using Docker. + +## Run + +To run this examples you will need to start containers with "docker-compose" +and after starting setup replication. See commands inside ./build.sh. + +#### Create 2 MySQL containers with master-slave row-based replication + +``` +./build.sh +``` + +#### Make changes to master + +``` +docker exec mysql_master sh -c "export MYSQL_PWD=111; mysql -u root mydb -e 'create table code(code int); insert into code values (100), (200)'" +``` + +#### Read changes from slave + +``` +docker exec mysql_slave sh -c "export MYSQL_PWD=111; mysql -u root mydb -e 'select * from code \G'" +``` + +## Troubleshooting + +#### Check Logs + +``` +docker-compose logs +``` + +#### Start containers in "normal" mode + +> Go through "build.sh" and run command step-by-step. + +#### Check running containers + +``` +docker-compose ps +``` + +#### Clean data dir + +``` +rm -rf ./master/data/* +rm -rf ./slave/data/* +``` + +#### Run command inside "mysql_master" + +``` +docker exec mysql_master sh -c 'mysql -u root -p111 -e "SHOW MASTER STATUS \G"' +``` + +#### Run command inside "mysql_slave" + +``` +docker exec mysql_slave sh -c 'mysql -u root -p111 -e "SHOW SLAVE STATUS \G"' +``` + +#### Enter into "mysql_master" + +``` +docker exec -it mysql_master bash +``` + +#### Enter into "mysql_slave" + +``` +docker exec -it mysql_slave bash +``` diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..24d023e --- /dev/null +++ b/build.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +docker-compose down +rm -rf ./master/data/* +rm -rf ./slave/data/* +docker-compose build +docker-compose up -d + +until docker exec mysql_master sh -c 'export MYSQL_PWD=111; mysql -u root -e ";"' +do + echo "Waiting for mysql_master database connection..." + sleep 4 +done + +priv_stmt='GRANT REPLICATION SLAVE ON *.* TO "mydb_slave_user"@"%" IDENTIFIED BY "mydb_slave_pwd"; FLUSH PRIVILEGES;' +docker exec mysql_master sh -c "export MYSQL_PWD=111; mysql -u root -e '$priv_stmt'" + +until docker-compose exec mysql_slave sh -c 'export MYSQL_PWD=111; mysql -u root -e ";"' +do + echo "Waiting for mysql_slave database connection..." + sleep 4 +done + +docker-ip() { + docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$@" +} + +MS_STATUS=`docker exec mysql_master sh -c 'export MYSQL_PWD=111; mysql -u root -e "SHOW MASTER STATUS"'` +CURRENT_LOG=`echo $MS_STATUS | awk '{print $6}'` +CURRENT_POS=`echo $MS_STATUS | awk '{print $7}'` + +start_slave_stmt="CHANGE MASTER TO MASTER_HOST='$(docker-ip mysql_master)',MASTER_USER='mydb_slave_user',MASTER_PASSWORD='mydb_slave_pwd',MASTER_LOG_FILE='$CURRENT_LOG',MASTER_LOG_POS=$CURRENT_POS; START SLAVE;" +start_slave_cmd='export MYSQL_PWD=111; mysql -u root -e "' +start_slave_cmd+="$start_slave_stmt" +start_slave_cmd+='"' +docker exec mysql_slave sh -c "$start_slave_cmd" + +docker exec mysql_slave sh -c "export MYSQL_PWD=111; mysql -u root -e 'SHOW SLAVE STATUS \G'" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..053c194 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +version: '3' +services: + mysql_master: +# image: mysql:5.7 + build: + context: ./master + env_file: + - ./master/mysql_master.env + container_name: "mysql_master" + restart: "no" + ports: + - 4406:4406 + volumes: + - ./master/conf/mysql.conf.cnf:/etc/mysql/conf.d/mysql.conf.cnf + - ./master/data:/var/lib/mysql + networks: + - overlay + + mysql_slave: + image: mysql:5.7 + env_file: + - ./slave/mysql_slave.env + container_name: "mysql_slave" + restart: "no" + ports: + - 5506:5506 + volumes: + - ./slave/conf/mysql.conf.cnf:/etc/mysql/conf.d/mysql.conf.cnf + - ./slave/data:/var/lib/mysql + networks: + - overlay + +networks: + overlay: + diff --git a/master/Dockerfile b/master/Dockerfile new file mode 100644 index 0000000..6386fcd --- /dev/null +++ b/master/Dockerfile @@ -0,0 +1,5 @@ +# see https://hub.docker.com/_/mysql/ + +FROM mysql:5.7 + +# RUN mysql -u root -e "GRANT REPLICATION SLAVE ON *.* TO 'mydb_slave_user'@'%' IDENTIFIED BY 'mydb_slave_pwd'; FLUSH PRIVILEGES;" diff --git a/master/conf/mysql.conf.cnf b/master/conf/mysql.conf.cnf new file mode 100644 index 0000000..4d44d2a --- /dev/null +++ b/master/conf/mysql.conf.cnf @@ -0,0 +1,9 @@ +[mysqld] + +skip-host-cache +skip-name-resolve + +server-id = 1 +log_bin = /var/log/mysql/mysql-bin.log +binlog_format = ROW +binlog_do_db = mydb diff --git a/master/data/.gitkeep b/master/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/master/mysql_master.env b/master/mysql_master.env new file mode 100644 index 0000000..cd63373 --- /dev/null +++ b/master/mysql_master.env @@ -0,0 +1,7 @@ +# Note, by default mysql root does not have a password. You need to restart a server to bring MYSQL_ROOT_PASSWORD working. Use "docker-compose restart" command. +MYSQL_ROOT_PASSWORD=111 +MYSQL_PORT=4406 +MYSQL_USER=mydb_user +MYSQL_PASSWORD=mydb_pwd +MYSQL_DATABASE=mydb +MYSQL_LOWER_CASE_TABLE_NAMES=0 diff --git a/slave/conf/mysql.conf.cnf b/slave/conf/mysql.conf.cnf new file mode 100644 index 0000000..bac2ed2 --- /dev/null +++ b/slave/conf/mysql.conf.cnf @@ -0,0 +1,9 @@ +[mysqld] + +skip-host-cache +skip-name-resolve + +server-id=2 +relay-log = /var/log/mysql/mysql-relay-bin.log +log_bin = /var/log/mysql/mysql-bin.log +binlog_do_db = mydb diff --git a/slave/data/.gitkeep b/slave/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/slave/mysql_slave.env b/slave/mysql_slave.env new file mode 100644 index 0000000..d92a45c --- /dev/null +++ b/slave/mysql_slave.env @@ -0,0 +1,7 @@ +# Note, by default mysql root does not have a password. You need to restart a server to bring MYSQL_ROOT_PASSWORD working. Use "docker-compose restart" command. +MYSQL_ROOT_PASSWORD=111 +MYSQL_PORT=5506 +MYSQL_USER=mydb_slave_user +MYSQL_PASSWORD=mydb_slave_pwd +MYSQL_DATABASE=mydb +MYSQL_LOWER_CASE_TABLE_NAMES=0