使用 docker 搭建主从服务器
首先拉取 docker 镜像:docker pull mysql:5.7
然后使用此镜像启动容器:
主:
docker run -p 3339:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
从:
docker run -p 3339:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
master 对外映射的端口是 3339, Slave 对外映射的端口是3340。因为 docker 容器是相互独立的,每个容器有其独立的 ip,所以不同的容器使用相同的端口不会冲突。
使用 docker ps -a
命令查看正在运行的容器:
配置 Master
使用 docker exec -it af2a2bfeb835 bash
或者 docker exec -it mysql-master /bin/bash
命令进入 docker 容器内部。
到 /etc/mysql
目录下编辑 my.cnf
文件,添加如下配置:
[mysqld]
log-bin=mysql-bin //[主库必须]启用二进制日志
server-id=222 //[主从必须]集群库唯一ID,默认是1,可以是任意,保证和其他库的不一样
注:如果 docker 中没有安装 vi ,需要执行 apt-get install vim
命令,如果不能开始安装,需要先执行 apt-get update
命令,再安装 vim。
配置 Slave
同样的,在 my.cnf 文件添加如下配置:
[mysqld]
log-bin=mysql-bin //[从库必须]启用二进制日志
server-id=223 //[主从必须]集群库唯一ID,默认是1,可以是任意,保证和其他库的不一样
relay_log=edu-mysql-relay-bin // 配置中继日志
## 一些非必须参数
auto_increment_increment=2 //[非必须]步进值auto_imcrement。一般有n台主MySQL就填n
auto_increment_offset=1 //[非必须]起始值。一般填第n台主MySQL。此时为第一台主MySQL
binlog-ignore-db=mysql //[非必须]忽略mysql库,多个库就重复一行
binlog-ignore-db=information_schema //[非必须]忽略mysql库,多个库就重复一行
replicate-do-db=user //[非必须]要同步的数据库,多个库就重复一行,默认所有库
replicate-do-db=demo //[非必须]要同步的数据库,多个库就重复一行,默认所有库
然后重启主从上的 MySQL 服务
创建账号
在 Master 数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE 权限和 REPLICATION CLIENT 权限,用于在主从库之间同步数据。
mysql> use mysql;
mysql> create user duzs identified by '123456'; // 创建用户名“duzs”,密码“123456”;
mysql> grant all on *.* to 'duzs'@'%'; // 授权给用户 duzs,% 代表所有 IP,可替换成具体的 IP
mysql> grant select,update,insert,delete on *.* to 'duzs'@'%'; // 给 duzs 用户增删改查的权限
mysql> flush privileges; // 刷新权限
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* to 'duzs'@'%' ; // 授权 slave
连接 Master 和 Slave
在 Master 进入MySQL,执行 show master status;
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 1189 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
此时不要做任何操作,以免改变 master 的状态
进入从库,配置从数据库:
mysql> change master to master_host='172.17.0.4',
master_user='duzs',master_password='123456',master_log_file='mysql-bin.000001',
master_log_pos=1189;
mysql> start slave; // 启动从主库同步功能,stop slave 停止
其中 master_host 是主库地址,指的是容器的独立 ip,可以通过 docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称|容器id
来获取
查看 slave 状态:
mysql> show slave status\G;
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.17.0.4 # 主服务器地址
Master_User: duzs # 授权用户名
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 1189 # 读取 binlog 的位置
Relay_Log_File: edu-mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes #必须为yes
Slave_SQL_Running: Yes
......
Slave_IO_Running 及 Slave_SQL_Running 进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)
如果使用 start slave 开启主从复制之后,Slave_IO_Running 一直是 connecting,说明主从复制一直处于连接状态,可以通过 Last_IO_Error 参数来排除:
- 网络不通 检查ip,端口
- 密码不对 检查是否创建用于同步的用户和用户密码是否正确
- pos不对 检查Master的 Position
那么问题来了,主从是如何保证数据一致的呢?https://www.jianshu.com/p/900e45426f3c