简介
MySQL 的主从同步是一个异步的复制过程,是从一个 Master 复制到另一个 Slave 上的过程。在 Master 与 Slave 之间的实现整个复制过程主要由3个线程来完成,其中有2个线程(SQL 线程和 IO 线程)在 Slave 端,另外一个线程(Binlog Dump 线程)在 Master 端。
要实现 MySQL 的主从同步,首先必须打开 Master 端的 BinaryLog(mysql-bin)功能,否则无法实现。因为整个复制过程实际上就是Slave从Master端获取该日志然后再在自己身上完成顺序的执行日志中所记录的各种操作。打开 MySQL 的 Binary Log 可以通过在启动 MySQL Server 的过程中使用 “—log-bin” 参数选项,或者在 my.cnf 配置文件中的 mysqld 参数组([ mysqld ]标识后的参数部分)增加 “log-bin” 参数项。
原理
(1) master 将改变记录存放到二进制日志( binary log )中(这些记录叫做二进制日志事件,binary log events),由Binlog Dump线程执行;
(2) slave 将 master 的 binary log events 拷贝到它的中继日志( relay log ) 中,由 Slave 端的 IO 线程执行;
(3) slave 重做中继日志中的事件,将改变反映它自己的数据,由 Slave 端的 Sql 线程执行;
(4) 如果是多线程复制,无论是 5.6 库级别的假多线程还是 MariaDB 或者 5.7 的真正的多线程复制, SQL 线程只做 coordinator,只负责把 relay log 中的 bin log 读出来然后交给 worker 线程, worker 线程负责具体 bin log event 的执行;
复制过程
MySQL 复制过程原理图
实列说明 MySQL 的主从复制架构和实现详细过程
配置步骤及说明
1、配置master
1)配置
server-id=1
log-bin=mysql-bin
#server-id:为主服务器A的ID值 log-bin:二进制变更日值
2)、重启master
docker中重启
docker restart [CONTAINER ID,容器id]
linux中重启
# a) 使用 service 启动:
service mysqld restart
service mysql restart (5.5.7版本命令)
# b) 使用 mysqld 脚本启动:
/etc/init.d/mysqld restart
运行SHOW MASTER STATUS;,输出如下:
状态结果
创建用户并授权:用户:repl密码:slavepass
mysql> CREATE USER 'repl'@'192.168.1.102' IDENTIFIED BY 'slavepass'; #创建用户
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.102'; #分配权限
mysql>flush privileges; #刷新权限
2、配置slave
1)配置
slave 的配置与 master 类似,你同样需要重启 slave 的 MySQL。如下:
log_bin = mysql-bin
server_id = 2
relay_log = mysql-relay-bin
log_slave_updates = 1
read_only = 1
server_id 是必须的,而且唯一。slave 没有必要开启二进制日志,但是在一些情况下,必须设置,例如,如果 slave 为其它 slave 的 master,必须设置 bin_log 。在这里,我们开启了二进制日志,而且显示的命名(默认名称为 hostname,但是,如果 hostname改变则会出现问题)。relay_log 配置中继日志,log_slave_updates 表示 slave 将复制事件写进自己的二进制日志(后面会看到它的用处)。有些人开启了 slave 的二进制日志,却没有设置 log_slave_updates,然后查看 slave 的数据是否改变,这是一种错误的配置。所以,尽量使用 read_only,它防止改变数据(除了特殊的线程)。但是,read_only 并是很实用,特别是那些需要在 slave 上创建表的应用。
启动 slave
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.1.101',
-> MASTER_PORT=3306,
-> MASTER_USER='rep1',
-> MASTER_PASSWORD='slavepass',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=155;
mysql> start slave;
3)查看 slave 状态
mysql> show slave status\G;
出现错误:
error connecting to master 'rep1@'192.168.1.101:3306' - retry-time: 60 retries: 4
解决办法:
docker start master-mysql 开始 Master mySql
docker ps -a 查出自己创建的 container(容器)的ID
docker exec -it 63c9e29aelef bash (每个人创建的 container ID 都不一样)
mysql --user=root --password
ALTER USER 'rep1'@'192.168.1.101' IDENTIFIED WITH mysql_native_password BY 'slavepass';
4)附加内容
停止 MySQL 同步
STOP SLAVE IO_THREAD; #停止 IO 进程
STOP SLAVE SQL_THREAD; #停止 SQL 进程
STOP SLAVE; #停止 IO 和 SQL 进程
启动 MySQL 同步
START SLAVE IO_THREAD; #启动 IO 进程
START SLAVE SQL_THREAD; #启动 SQL 进程
START SLAVE; #启动 IO 和 SQL 进程
重置 MySQL 同步
RESET SLAVE;