MySQL主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点,如下图所示:
主节点 binary log dump 线程
当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。
从节点I/O线程
当从节点上执行start slave命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。
从节点SQL线程
SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。
要实施复制,首先必须打开Master 端的binary log(bin-log)功能,否则无法实现。
因为整个复制过程实际上就是Slave 从Master 端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。如下图所示:
复制的基本过程如下:
== 从节点上的I/O 进程连接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
主节点接收到来自从节点的I/O请求后,通过负责复制的I/O进程根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的bin-log file 的以及bin-log position;
从节点的I/O进程接收到内容后,将接收到的日志内容更新到本机的relay log中,并将读取到的binary log文件名和位置保存到master-info 文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log 的哪个位置开始往后的日志内容,请发给我”;
Slave 的 SQL线程检测到relay-log 中新增加了内容后,会将relay-log的内容解析成在主节点上实际执行过的操作,并在本数据库中执行。==
2.Mysql的主从异步复制(Asynchronous replication)
1、逻辑上
MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从库上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
2、技术上
主库将事务 Binlog 事件写入到 Binlog 文件中,此时主库只会通知一下 Dump 线程发送这些新的 Binlog,然后主库就会继续处理提交操作,而此时不会保证这些 Binlog 传到任何一个从库节点上。
(2)异步复制的实现:
所需环境:主库:172.25.15.1 server1
从库:172.25.15.2 server2
两个7.3的虚拟机镜像
将rpm包从真机传给虚拟机,然后进行安装
安装完成后:修改配置文件,启动数据库,并获得生成的初始密码:
vim /etc/my.cnf
systemctl start mysqld
cat /var/log/mysqld.log | grep password
数据库安全初始化,并使用新密码登陆:
mysql_secure_installation
初始化成功
登陆
创建用来主从复制的用户repl,查看主节点状态:
show plugins; 查看限制密码插件
show master status; 查看节点状态
真机测试,repl用户能否登陆:
mysql -h 172.25.15.1 -urepl -p 登陆成功
从库的操作如下:
安装rpm包:
vim /etc/my.cnf
systemctl start mysqld 查看密码并安全初始化
cat /var/log/mysqld.log | grep password
mysql_secure_installation
登陆数据库设置,并开启从节点:
mysql> CHANGE MASTER TO
-> MASTER_HOST=‘172.25.15.1’, 主节点ip
-> MASTER_USER=‘repl’,
-> MASTER_PASSWORD=‘Yty123+ld’,
-> MASTER_LOG_FILE=‘mysql-bin.000002’, 所读数据目录
-> MASTER_LOG_POS=1011; 所读数据位置 同步数据的起始位置
Query OK, 0 rows affected, 2 warnings (0.30 sec)
start slave; 开启从库
mysql> show slave status\G #查看从节点状态
Slave_IO_Running: Yes #这两行必须是yes,否则有问题
Slave_SQL_Running: Yes
这样,主从异步复制就已经实现了,进行测试
主节点的操作:
==desc usertb; == #查看表结构
mysql> select * from usertb; #查看表中所有内容
从节点的操作:
可以看到westos库
可以看到表中所有内容