Back
Featured image of post MySQL主从复制搭建与原理

MySQL主从复制搭建与原理

主从复制搭建

拉取镜像

用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就成功了

原理解析

基本过程

  1. master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
  2. slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件
  3. 同时主节点为每个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语句逐一执行;

注意

  1. master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。
  2. slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。
  3. MySQL复制至少需要两个Mysql的服务,当然MySQL服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。
  4. MySQL复制最好确保master和slave服务器上的MySQL版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)
  5. master和slave两节点间时间需同步
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
一辈子热爱技术
Built with Hugo
Theme Stack designed by Jimmy
gopher