主从复制搭建
拉取镜像
用docker,mysql5.7
docker pull mysql:5.7
启动
主节点
docker run -p 3306:3306 --name mysql_master -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
从节点
docker run -p 3306:3306 --name mysql——slave -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
Master配置
通过docker exec -it [容器名] bash
进入容器内部
安装vim
apt-get update
apt-get install vim
编辑配置文件my.cnf
cd /etc/mysql
vim my.cnf
添加以下内容
[mysqld]
## 同一局域网内注意要唯一
server-id=100
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
完成后重启服务,重启服务后需要重启容器
service mysql restart
docker start mysql_master
再次进入容器,创建用于同步数据的用户
mysql -hlocalhost -uroot -p
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
flush privileges;
Slave配置
和Master一样要安装vim,然后在my.cnf中添加
[mysqld]
## 设置server_id,注意要唯一
server-id=101
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
然后也要经过一样的重启过程
链接Master和Slave
先在master里mysql中执行
show master status;
其中File字段和Position字段待会要用到,此时开始master不要再做任何操作,保证Position字段的值不再改变
然后进入salve的mysql中执行
change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos= 769, master_connect_retry=30;
- master_host :Master的ip地址
- master_port:Master的端口号
- master_user:用于数据同步的用户
- master_password:用于同步的用户的密码
- master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
- master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
- master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
最后每台slave都执行
start slave;
查询主从复制状态
show slave status \G;
有2个yes就成功了
原理解析
基本过程
- master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
- slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件
- 同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志(relay log)中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后 I/O Thread 和 SQL Thread 将进入睡眠状态,等待下一次被唤醒。
要点
- 从库会生成两个线程,一个I/O线程,一个SQL线程;
- I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;
- 主库会生成一个log dump线程,用来给从库I/O线程传binlog;
- SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;
注意
- master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。
- slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。
- MySQL复制至少需要两个Mysql的服务,当然MySQL服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。
- MySQL复制最好确保master和slave服务器上的MySQL版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)
- master和slave两节点间时间需同步