MySQL主从复制

MySQL Replication

作用

  • Replication可以将一台主服务器数据库(master)同步到一台或多台从服务器数据库(slave)
  • 其复制方式属于异步复制无需要长时间连接
  • Replication是MySQL内建自带的

主从复制原理

简单的说就是 master 将数据库的改变写入二进制日志, slave 同步这些二进制日志,并根据这些二进制日志进行数据操作

  • master记录二进制日志文件 在每个事物更新数据完成之前 master在二进制日志文件记录这些改变的数据 MySQL将事物写入二进制日志文件中 在事件写入二进制日志完成之后 master通知存储引擎提交事务
  • slave将master的binary log拷贝到自己的中继日志文件 首先slave会执行I/O thread线程 I/O线程会在master上打开一个普通的链接 然后开始binlog dump process binlog dump process从master读取二进制文件 如果已经读取完master的二进制日志文件 其会进入休眠状态并等待产生新的日志文件 同时将读取的事件写入到自己的中继日志文件
  • SQL从线程处理最后一步 SQL从线程读取中继日志的事件且执行其中的事件 使master与slave数据保持一致

Replication作用

  • 故障切换
  • 备份服务 但是无法对SQL语句产生的故障就行恢复 有限的备份
  • 可以多台slave实现读写分离

Replication原理

  • master将改变的记录写到(binary log)二进制日志文件中
  • slave将master上二进制日志(binary log)日志拷贝到自己的中继日志(Relay log)
  • slave读取中级日志的内容 修改slave的数据

常见MySQL主从复制架构

一主多备(One master and Muti salve)

  • 一般适用于做读写分离 master进行数据写入 slave进行数据读取
  • master压力较大需要与多台slave有I/O操作

slave中继

  • 使用一台slave作为中继设备缓解master的压力
  • slave需要开启bin-log并且配置log-slave-updates
  • slave作为中转设备可以使用黑洞引擎无需承载数据

双主互备

  • 服务器之间互相成为master与slave
  • 其破坏了事务的隔离性与一致性

MySQL主从配置

主从配置

在配置之前保证mysql的版本一致 防止出现未知的错误

master配置

# 首先创建数据库 创建表格
mysql> create database  TestMasterSlave;
Query OK, 1 row affected (0.00 sec)

mysql> use TestMasterSlave;
Database changed

mysql> create table test(id int,name varchar(254));
Query OK, 0 rows affected (0.01 sec)

mysql> grant replication slave on *.* to slave@'10.1.1.%' identified by "root123";      # 设置授权账号 slave通过该账号访问master

mysql> show master status;
+-------------------------+----------+-----------------+------------------+-------------------+
| File                    | Position | Binlog_Do_DB    | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------------+----------+-----------------+------------------+-------------------+
| mysql-master-log.000001 |      597 | TestMasterSlave | mysql            |                   |
+-------------------------+----------+-----------------+------------------+-------------------+

[root@master ~]# systemctl stop firewalld.service && iptables -F && setenforce 0      # 关闭防火墙

[root@master~]# mysqldump -uroot -proot123 -B > test.sql      # 将主服务器中数据库表结构导出 

[root@master~]# scp test.sql 10.1.1.2:/root/      # 将导出的数据库传递给slave

[root@master~]# vim /etc/my.cnf
      server-id=1      # 配置服务ID
      log-bin=mysql-master-log      # 配置二进制文件
      binlog-do-db=TestMasterSlave      # 需要同步的数据库
      binlog-ignore-db=mysql      # 忽略的数据库 即不需要同步

[root@master~]# systemctl restart mysqld      # 重启mysql服务

slave配置

[root@slave~]# systemctl stop firewalld.service && iptables -F && setenforce 0      # 关闭防火墙

[root@slave~]# mysql -e 'create database TestMasterSlave' -u root -p      # 创建数据库

[root@slave ~]# mysql -uroot -p <test.sql      #  同步master传来的数据库
[root@slave ~]# vim /etc/my.cnf
      server-id=2      # 每台服务器的server-id必须唯一
[root@slave ~]# systemctl restart mysqld      # 重启mysql
[root@slave ~]# mysql -uroot -p      # 进入mysql
mysql> stop slave;      # 先停止中继线程

mysql> change master to master_host='10.1.1.1' ,master_user='slave' ,master_password='root123';      # 使用授权账号进行数据同步
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;      # 开启slave

mysql> show slave status\G;   slave状态查询   # 进行

测试数据

# master插入数据
mysql> use TestMasterSlave;

mysql> insert into test values(1,'SR');

# slave查看数据
mysql> use TestMasterSlave;

mysql> show tables;
+---------------------------+
| Tables_in_TestMasterSlave |
+---------------------------+
| test                      |      # 表格同步
+---------------------------+
1 row in set (0.00 sec)

mysql> select * from test;
+------+------+
| id   | name |
+------+------+
|    1 | SR   |      # 数据同步
+------+------+

双向主从

master

[root@master ~]# vim /etc/my.cnf
      server-id=1
      log-bin=mysql-bin-master
      binlog-do-db=test
      binlog-ignore-db=mysql

mysql> grant replication slave on *.* to slave@'10.1.1.%' identified by "root123";      # 设置授权账号

mysql> stop slave; 
mysql> change master to master_host='10.1.1.2',master_user='slave',master_password='root123';      # 设置master
mysql> start slave; 
mysql> show slave status; 

slave

[root@slave ~]# vim /etc/my.cnf
      server-id=2
      log-bin=mysql-master-bin
      binlog-do-db=test
      binlog-ignore-db=mysql

mysql> grant replication slave on *.* to slave@'10.1.1.%' identified by "root123";      # 设置授权账号

mysql> stop slave; 
mysql> change master to master_host='10.1.1.1',master_user='slave',master_password='root123';      # 设置master
mysql> start slave; 
mysql> show slave status; 

测试数据

# 10.1.1.1插入数据
mysql> use test;

mysql> create table test(id int, name varchar(254));

mysql> insert into test values(1,'SR');

# 10.1.1.2查看数据

mysql> select * from test;
+------+------+
| id   | name |
+------+------+
|    1 | SR   |
+------+------+

# 10.1.1.2插入数据

mysql> insert into test values(2,'MZ');
mysql> select * from test;
+------+------+
| id   | name |
+------+------+
|    1 | SR   |
|    2 | MZ   |
+------+------+

中继主从复制

master

[root@master ~]# vim /etc/my.cnf
    server-id=1
    log-bin=master-bin-log
    binlog-do-db=test
    binlog-ignore-db=mysql
    sync_binlog=1      # binlog写入到硬盘
    binlog-format=row      # binlog以行格式化输出
[root@master ~]# systemctl restart mysqld

mysql> grant replication slave on *.* to slave@'10.1.1.%' identified by "root123"; 

relay中继

[root@relay ~]# vim /etc/my.cnf
      server-id=2
      log-bin=relay-bin-log      # 二进制日志
      log-slave-updates=1      # 从relay-log读取的日志文件以及本机进行的操作写到中继日志里 这样slave才能知道数据变化
      binlog-format=row
[root@relay ~]# systemctl restart mysqld

mysql> grant replication slave on *.* to relay@'10.1.1.%' identified by "root123";

mysql> stop slave;

mysql> change master to master_host='10.1.1.1',master_user='slave',master_password='root123';    


mysql> start slave;
  

slave

[root@slave ~]# vim /etc/my.cnf
      
      server-id=3
      log-bin=slave-bin-log
      binlog-format=row
[root@slave ~]# systemctl restart mysqld
mysql> stop slave; 
mysql> change master to master_host='10.1.1.1',master_user='relay',master_password='root123';      # 设置master
mysql> start slave; 
mysql> show slave status; 

测试数据

mysql> create database HA;
mysql> use HA
mysql> create table test(id int,name varchar(20));
mysql> insert into test values (1,'AA');
Query OK, 1 row affected (0.09 sec)

relay

mysql> set sql_log_bin=off;

mysql> alter table test ENGINE=blackhole;      # 将存储引擎修改为黑洞引擎 则中继不会保存数据

mysql> select * from test;
Empty set (0.01 sec)

slave

mysql> select * from test;
posted @ 2020-07-24 09:39  SR丶  阅读(159)  评论(0编辑  收藏  举报