MySQL本地主从搭建


本文记录了在本地使用Docker搭建MySQL一主多从的配置文件、脚本文件以及启动过程。

环境设置

  • Docker: v20.10.24

  • MacOS: v13.3

  • MySQL: v5.7

配置文件

Master

  • master.cnf
[mysqld]
#开启binlog日志
log-bin=mysql-bin
#设置服务id,主从不能一致
server-id=1
#屏蔽系统库同步
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema

Slave

  • slave1.cnf
[mysqld]
#开启binlog日志
log-bin=mysql-bin
#设置服务id,主从不能一致
server-id=2

# 设置忽略的库
replicate_wild_ignore_table=mysql.%
replicate_wild_ignore_table=information_schema.%
replicate_wild_ignore_table=performance_schema.%
  • slave2.cnf
[mysqld]
#开启binlog日志
log-bin=mysql-bin
#设置服务id,主从不能一致
server-id=3

# 设置忽略的库
replicate_wild_ignore_table=mysql.%
replicate_wild_ignore_table=information_schema.%
replicate_wild_ignore_table=performance_schema.%

脚本文件

Master

  • master.sh
#!/bin/bash

DOCKER_INSTANCE_NAME=master
MYSQL_ROOT_PASSWORD=master
CONTAINER_PORT=3306
HOST_PORT=13306
CONTAINER_CONFIG_PATH=/etc/my.cnf
HOST_CONFIG_PATH=/Users/foursevenlove/Desktop/scripts/mysql-master-slave/master.cnf
CONTANIER_DATA_PATH=/var/lib/mysql
HOST_DATA_PATH=/Users/foursevenlove/Desktop/scripts/mysql-master-slave/data/master

docker stop "${DOCKER_INSTANCE_NAME}" >/dev/null 2>&1
docker rm "${DOCKER_INSTANCE_NAME}" >/dev/null 2>&1

docker run \
    --name ${DOCKER_INSTANCE_NAME} \
    -v ${HOST_CONFIG_PATH}:${CONTAINER_CONFIG_PATH} \
    -v ${HOST_DATA_PATH}:${CONTANIER_DATA_PATH} \
    -e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \
    -p ${HOST_PORT}:${CONTAINER_PORT} \
    -d \
    mysql:5.7 >/dev/null

if [ $? -eq 0 ]; then
    echo "Docker container '${DOCKER_INSTANCE_NAME}' started successfully."
else
    echo "Failed to start Docker container '${DOCKER_INSTANCE_NAME}'."
fi

Slave

  • slave1.sh
#!/bin/bash

DOCKER_INSTANCE_NAME=slave
MYSQL_ROOT_PASSWORD=slave
CONTAINER_PORT=3306
HOST_PORT=23306
CONTAINER_CONFIG_PATH=/etc/my.cnf
HOST_CONFIG_PATH=/Users/foursevenlove/Desktop/scripts/mysql-master-slave/slave.cnf
CONTANIER_DATA_PATH=/var/lib/mysql
HOST_DATA_PATH=/Users/foursevenlove/Desktop/scripts/mysql-master-slave/data/slave

docker stop "${DOCKER_INSTANCE_NAME}" >/dev/null 2>&1
docker rm "${DOCKER_INSTANCE_NAME}" >/dev/null 2>&1

docker run \
    --name ${DOCKER_INSTANCE_NAME} \
    -v ${HOST_CONFIG_PATH}:${CONTAINER_CONFIG_PATH} \
    -v ${HOST_DATA_PATH}:${CONTANIER_DATA_PATH} \
    -e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \
    -p ${HOST_PORT}:${CONTAINER_PORT} \
    -d \
    mysql:5.7 >/dev/null

if [ $? -eq 0 ]; then
    echo "Docker container '${DOCKER_INSTANCE_NAME}' started successfully."
else
    echo "Failed to start Docker container '${DOCKER_INSTANCE_NAME}'."
fi
  • slave2.sh
#!/bin/bash

DOCKER_INSTANCE_NAME=slave2
MYSQL_ROOT_PASSWORD=slave2
CONTAINER_PORT=3306
HOST_PORT=33306
CONTAINER_CONFIG_PATH=/etc/my.cnf
HOST_CONFIG_PATH=/Users/foursevenlove/Desktop/scripts/mysql-master-slave/slave2.cnf
CONTANIER_DATA_PATH=/var/lib/mysql
HOST_DATA_PATH=/Users/foursevenlove/Desktop/scripts/mysql-master-slave/data/slave2


docker stop "${DOCKER_INSTANCE_NAME}" >/dev/null 2>&1
docker rm "${DOCKER_INSTANCE_NAME}" >/dev/null 2>&1

docker run \
    --name ${DOCKER_INSTANCE_NAME} \
    -v ${HOST_CONFIG_PATH}:${CONTAINER_CONFIG_PATH} \
    -v ${HOST_DATA_PATH}:${CONTANIER_DATA_PATH} \
    -e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \
    -p ${HOST_PORT}:${CONTAINER_PORT} \
    -d \
    mysql:5.7 >/dev/null

if [ $? -eq 0 ]; then
    echo "Docker container '${DOCKER_INSTANCE_NAME}' started successfully."
else
    echo "Failed to start Docker container '${DOCKER_INSTANCE_NAME}'."
fi

Start

  • start.sh
#! /bin/bash

SCRIPTS_DIR=/Users/foursevenlove/Desktop/scripts/mysql-master-slave

sh ${SCRIPTS_DIR}/master.sh
sh ${SCRIPTS_DIR}/slave.sh
sh ${SCRIPTS_DIR}/slave2.sh

启动过程

在准备好上述配置文件和脚本文件后,就可以开始启动数据库。

首先执行以下命令启动主从数据库,看到以下日志代表成功启动数据库实例:

> sh ./start.sh
Docker container 'master' started successfully.
Docker container 'slave' started successfully.
Docker container 'slave2' started successfully.

通过docker查看数据库实例:

> docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS         PORTS                                                                                                                                  NAMES
0061e924d5cb   mysql:5.7                "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   33060/tcp, 0.0.0.0:33306->3306/tcp                                                                                                     slave2
8995ce05c39d   mysql:5.7                "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   33060/tcp, 0.0.0.0:23306->3306/tcp                                                                                                     slave
51c14e787f46   mysql:5.7                "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   33060/tcp, 0.0.0.0:13306->3306/tcp

Master

登录Master数据库,创建主从复制权限的账户:

  • 通过docker exec命令与容器交互
> docker exec -it master /bin/bash
  • 登录root用户,输入密码:
> mysql -uroot -p
  • 创建主从复制权限的账户:
GRANT REPLICATION SLAVE ON *.* TO 'db_sync'@'%' IDENTIFIED BY 'db_sync';
FLUSH PRIVILEGES;
  • 查看master bin log文件名和position,根据结果文件名为mysql-bin.000006,position为592:
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+---------------------------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                            | Executed_Gtid_Set |
+------------------+----------+--------------+---------------------------------------------+-------------------+
| mysql-bin.000006 |      592 |              | mysql,information_schema,performance_schema |                   |
+------------------+----------+--------------+---------------------------------------------+-------------------+
1 row in set (0.00 sec)

查看Master所在容器IP,下面Slave启动需要用到:

> docker inspect --format '{{ .NetworkSettings.IPAddress }}' master
172.17.0.3

Slave

下面是slave的启动过程,对于slave2操作过程类似。

  • 通过docker exec命令与容器交互
docker exec -it slave /bin/bash
  • 登录root用户,输入密码:
mysql -uroot -p
  • 确保slave没有启动:
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
  • 设置主库信息,其中master_host是上述查看的主库容器IP、master_user和master_password是在主库设置的有主从复制的账户、master_log_file和master_log_pos参数是上述提到的binlog文件名和指针位置:
mysql> change master to master_host='172.17.0.3', master_user='db_sync', master_password='db_sync', master_port=3306, master_log_file='mysql-bin.000006', master_log_pos=592;
Query OK, 0 rows affected, 2 warnings (0.28 sec)
  • 启动slave进程:
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
  • 通过以下命令查看slave是否启动成功,Slave_IO_Running和Slave_SQL_Running参数的值为Yes代表启动成功:
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.3
                  Master_User: db_sync
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 592
               Relay_Log_File: 8995ce05c39d-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table: mysql.%,information_schema.%,performance_schema.%
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 592
              Relay_Log_Space: 534
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: 6bcf284e-004c-11ee-98e0-0242ac110003
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

验证

在主库上新建一个测试DB,创建一张测试表,插入一些测试数据,再登录从库查看数据。

Master

  • 登录主库
> docker exec -it master /bin/bash
> mysql -uroot -p
  • 创建测试数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.09 sec)

mysql> create database testDB;
Query OK, 1 row affected (0.02 sec)
  • 创建测试表:
mysql> CREATE TABLE `t` (
    ->   `ftime` datetime NOT NULL,
    ->   `c` int(11) DEFAULT NULL,
    ->   PRIMARY KEY (`ftime`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.10 sec)
  • 插入测试数据:
mysql> insert into t values('2017-4-1',1),('2018-4-1',1),('2019-4-1',1),('2020-4-1',1),('2021-4-1',1);
Query OK, 5 rows affected (0.03 sec)
Records: 5  Duplicates: 0  Warnings: 0

Slave

  • 登录从库:
> docker exec -it slave /bin/bash

> mysql -uroot -p
  • 查看测试数据:
mysql> select * from testDB.t;
+---------------------+------+
| ftime               | c    |
+---------------------+------+
| 2017-04-01 00:00:00 |    1 |
| 2018-04-01 00:00:00 |    1 |
| 2019-04-01 00:00:00 |    1 |
| 2020-04-01 00:00:00 |    1 |
| 2021-04-01 00:00:00 |    1 |
+---------------------+------+
5 rows in set (0.00 sec)

文章作者: foursevenlove
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 foursevenlove !
  目录