原理:
MySQL使用3个线程来执行复制功能(其中1个在【主服务器】上,另两个在【从服务器】上。
当【从服务器】发出START SLAVE时,【从服务器】创建一个I/O线程,以连接【主服务器】并让它发送记录在其二进制日志中的语句。
【主服务器】创建一个线程将二进制日志中的内容发送到【从服务器】。该线程可以识别为【主服务器】上SHOW PROCESSLIST的输出中的Binlog Dump线程。
【从服务器】I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到【从服务器】数据目录中的本地文件中,即中继日志。第3个线程是SQL线程,是【从服务器】创建用于读取中继日志并执行日志中包含的更新。
我准备的环境:
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
使用oneinstack安装mysql
MySQL [(none)]> status;
--------------
mysql Ver 14.14 Distrib 5.7.19, for linux-glibc2.12 (x86_64) using EditLine wrapper
........
Server version: 5.7.19-log MySQL Community Server (GPL)
【主服务器】
首先查看mysql的配置文件
[root@localhost ~]# vi /etc/my.cnf
查找log_bin = mysql-bin
,如果此行是#开头,去掉#。如果不存在此行,手动添加。
查找server-id = 1
,记住【主服务器】的id,不能和【从服务器】重复。数字推荐写ip尾数。
如果修改了配置文件,需要重启mysql。
然后查看log_bin是否开启
MySQL [(none)]> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
接下来,查看master状态:
MySQL [(none)]> show master status;
+------------------+----------+---
| File | Position |
+------------------+----------+---
| mysql-bin.000017 | 503 |
+------------------+----------+---
1 row in set (0.00 sec)
File列显示日志名,而Position显示偏移量。在该例子中,二进制日志值为mysql-bin.000017,偏移量为503。记录该值。以后设置从服务器时需要使用这些值。它们表示复制坐标,【从服务器】应从该点开始从【主服务器】上进行新的更新。
创建用户,用来给【从服务器】访问。
语句:GRANT REPLICATION SLAVE ON 数据库名.表名 TO '用户名'@'来源' IDENTIFIED BY '用户密码';
本例:
MySQL [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%' IDENTIFIED BY 'mysql';
【从服务器】
首先查看mysql的配置文件
[root@localhost ~]# vi /etc/my.cnf
查找server-id = 1
,改成别的,不能和【主服务器】重复。
然后查看
[root@localhost ~]# vi /data/mysql/auto.cnf
[auto]
server-uuid=8a886b36-7b9e-11e7-9c15-080027bbb6b4
这里的server-uuid的值必须与主服务器不同,否则会报错。笔者是用的复制虚拟机,所以会遇到这种情况。
下面关键部分来了:
MySQL [(none)]> CHANGE MASTER TO
-> MASTER_HOST='192.168.1.103',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='mysql',
-> MASTER_LOG_FILE='mysql-bin.000017',
-> MASTER_LOG_POS=503;
所有配置都要与【主服务器】的信息匹配。
然后
MySQL [(none)]> start slave;
如果需要修改前面的项:
MySQL [(none)]> stop slave;
MySQL [(none)]> reset slave;
MySQL [(none)]> CHANGE MASTER TO
-> MASTER_HOST='192.168.1.103',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='mysql',
-> MASTER_LOG_FILE='mysql-bin.000017',
-> MASTER_LOG_POS=503;
MySQL [(none)]> start slave;
设置完成后,查看【从服务器】状态:
MySQL [(none)]> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.103
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000017
Read_Master_Log_Pos: 503
Relay_Log_File: localhost-relay-bin.000003
Relay_Log_Pos: 669
Relay_Master_Log_File: mysql-bin.000017
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
最后2行,必须都是Yes,如果是No或者Connecting都不行,可查看mysql-error.log,以排查问题。
MySQL [(none)]> show variables like 'log_error%';
+---------------------+-----------------------------+
| Variable_name | Value |
+---------------------+-----------------------------+
| log_error | /data/mysql/mysql-error.log |
| log_error_verbosity | 3 |
+---------------------+-----------------------------+
2 rows in set (0.00 sec)
配置完成后,【从服务器】会自动与【主服务器】同步。
经本人测试,如果【主服务器】重启mysql服务,【从服务器】会等待与【主服务器】重连,此时可查看到这些异常状态:
MySQL [(none)]> show slave status \G;
Slave_IO_State: Reconnecting after a failed master event read
Last_IO_Errno: 2003
Last_IO_Error: error reconnecting to master
Last_IO_Error_Timestamp: 170810 00:43:09
当主服务器恢复正常后,从服务器会自动重新连接上主服务器,并正常同步数据。
最后要补充一点百度知道上搜的,还没测:
设置主从同步或双主同步的话证明两台服务器日志模式都是bin-log模式,如果其中有一台服务器意外宕机,此时会导致同步中断。
恢复方法很简单:进入主机服务器(正常机器),在bin-log中找到出错时最接近错误标记的一个position,然后将宕机的服务器数据库执行change master,将master_log_file和master_log_pos重新指定一下就可以了
查看binlog:
MySQL [(none)]> show binlog events in 'mysql-bin.000017';