MySQL主从复制

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就是全局的.

image

上图就是一个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去获取日志文件,进行同步

image

如果使用的是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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值