MySQL主从复制
文章目录
1.主从复制和GTID主从的原理
-
普通主从复制:
主库将所有的写操作记录到binlog日志中并生成一个log dump线程,将binlog日志传给从库的I/O线程
从库生成两个线程,一个I/O线程,一个SQL线程
- I/O线程去请求主库的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中
- SQL线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,达到最终数据一致的目的
-
GTID 主从:
1、当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。
2、binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值。
3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID。
4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
5、如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行。
6、在解析过程中会判断是否有主键,如果有就用二级索引,如果没有就用全部扫描。
2.主从复制和GTID的区别
两者都是日志文件里事件的一个标志,如果将整个mysql集群看作一个整体,pos就是局部的,GTID就是全局的.
上图就是一个mysql节点的集群,一主两从,在master,slave1,slave2日志文件里的pos,都各不相同,就是一个event,在master的日志里,pos可能是700,而在slave1,slave2里,pos可能就是300,400了,因为众多slave也可能不是同时加入集群的,不是从同一个位置进行同步.
而GTID,在master,slave1,slave2各自的日志文件里,同一个event的GTID值都是一样的.
大家都知道,这整个集群架构的节点,通常情况下,是master在工作,其他两个结点做备份,而且,各个节点的机器,性能不可能完全一致,所以,在做备份时,备份的速度就不一样,当master突然crash掉之后,马上会启用从节点机器,接管master的工作,当有多个从节点时,选择备份日志文件最接近master的那个节点
现在就出现情况了,当salve1变成主节点,那slave2就应该从slave1去获取日志文件,进行同步
如果使用的是pos,三者的pos不一致,slave2怎么去获取它当前要同步的事件在slave1里的pos呢,很难.
所以就有了GTID,全局的,将所有节点对于同一个event的标记完全一致,当master crash掉之后,slave2根据同一个GTID直接去读取slave1的日志文件,继续同步.
3.MySQL主从复制
主库配置
准备工作 准备两台虚拟机(要求,两台服务器操作系统版本一致,数据库版本一致,数据也一致)
3.1关闭防火墙和selinux
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# systemctl disable firewalld.service
[root@localhost ~]# setenforce 0
[root@localhost ~]# vi /etc/sysconfig/selinux
SELINUX=disabled
3.2在主数据库里创建一个同步账号授权给从数据库使用
mysql> CREATE USER 'repl'@'192.168.132.100' IDENTIFIED BY 'runtime123';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.132.100';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
3.3配置主数据库
[root@localhost ~]# vim /etc/my.cnf
log-bin=mysql-bin //启用binlog日志
server-id=10 //数据库服务器唯一标识符,主库的server-id值必须比从库的大
重启服务
[root@localhost ~]# systemctl restart mysqld.service
[root@localhost ~]# ss -antul
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 80 *:3306 *:*
tcp LISTEN 0 128 [::]:22 [::]:*
查看主库状态
mysql> show master status;
+------------------+----------+--------------+------------------+-----------------
--+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Se
t |
+------------------+----------+--------------+------------------+-----------------
--+
| mysql-bin.000001 | 154 | | |
|
+------------------+----------+--------------+------------------+-----------------
--+
1 row in set (0.00 sec)
从库设置
关闭防火墙
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# systemctl disable firewalld.service
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@localhost ~]# setenforce 0
setenforce: SELinux is disabled
[root@localhost ~]# vim /etc/sysconfig/selinux
从库配置文件
[root@localhost ~]# vim /etc/my.cnf
server-id=20
relay-log=mysql-relay-bin //开启中继日志
mysql> change master to master_host='192.168.132.135', master_user='repl', master_password='runtime123', master_log_file='mysql-bin.000001',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
//查看从服务器状态
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.132.135
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 154
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes //这里必须为yes
Slave_SQL_Running: Yes //这里必须为yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
测试
在主库上创建一个数据库
mysql> create database lx;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| lx |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
从库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| lx |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
4.GTID主从
主库
关闭防火墙
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# systemctl disable firewalld.service
[root@localhost ~]# setenforce 0
[root@localhost ~]# vi /etc/sysconfig/selinux
SELINUX=disabled
主库配置文件
[root@localhost ~]# vim /etc/my.cnf
log-bin=mysql-bin
server-id=10
gtid_mode=on
enforce-gtid-consistency=true
log-slave-updates=on
[root@localhost ~]# systemctl restart mysqld.service
复制授权用户
mysql> grant replication slave on *.* to 'repl'@'%' identified by 'runtime123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
从库
配置文件
[root@localhost ~]# vim /etc/my.cnf
server-id=20
relay-log=myrelay
gtid_mode=on
enforce-gtid-consistency=true
log-slave-updates=on
read_only=on
master-info-repository=TABLE
relay-log-info-repository=TABLE
从库设置要同步的主库信息,并开启同步
mysql> change master to master_host='192.168.132.135' ,master_port=3306,master_user='repl' ,master_password='runtime123' ,master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> reset slave;
Query OK, 0 rows affected (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.132.135
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 437
Relay_Log_File: myrelay.000003
Relay_Log_Pos: 650
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
测试
主库
mysql> create database nidaye;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| lx |
| mysql |
| nidaye |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
从库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| lx |
| mysql |
| nidaye |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)