MySQL的复制

MySQL的复制,也叫主从复制,AB复制等等。
复制主要是实现数据同步,实时备份的作用,防止一个MySQL服务器暴毙影响Web服务。

常见的复制模式:
一主一从 :AB
两主 :AA
一主多从 :ABBBB…
两主两从 :AABB
级联 :ABBAB 跨机房。

基本的AB复制:

环境1库已将运行了一段时间,2库是空库。

原理:
概述
就是讲一个MySQL(Master,主服务器)中的数据同步给另一个MySQL(Slave,从服务器)服务,实现数据的共享,当Master的MySQL服务炸了,可以直接将Slave顶上去。而且这个共享是个异步过程。

工作原理

主从复制涉及到三个线程,一个在主服务器上,两个在从服务器上。log dump thread,日志记录,这个在主服务器上。I/O thread,IO线程和SQL thread,SQL线程在从服务器上。

在这里插入图片描述

如图所示
主节点 binary log dump 线程

当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送二进制日志的内容。在读取二进制日志中的操作时,此线程会对主节点上的二进制日志加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。

从节点I/O线程

当从节点上执行start slave 命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的二进制日志。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地中继日志中。

从节点SQL线程

SQL线程负责读取中继日志中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。

对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如,如果从节点没有运行,此时I/O进程可以很快从主节点获取更新,尽管SQL进程还没有执行。如果在SQL进程执行之前从节点服务停止,至少I/O进程已经从主节点拉取到了最新的变更并且保存在本地relay日志中,当服务再次起来之后,就可以完成数据的同步。

要实施复制,首先必须打开Master 端的记录二进制日志的功能,否则无法实现。

复制的过程就是从Master端获取更新的内容,再在salve上执行。

过程如下 :

1、Salve的IO进程请求Master,请求从二进制日志(binary log)的某个位置那个个位置就是Position,从这之后的日志内容。

2、Master收到Slave 的请求后根据IO中包含的信息,这个信息有两个,1是二进制日志文件(binary log)的位置2是最新位置信息position。将符合的部分返回给IO线程。
3、Slave收到Master的响应后,将内容存到自己的中继日志(relay log)中,并将读取到的二进制日志(binary log)文件名和位置保存到master-info 文件中,以便下次读取。
4、slave 的SQL线程读取到中继日志的更新,在数据库执行这些更新。至此,复制操作完成,slave和master的数据同步。

二进制日志中的文件就是SQL语句,换句话说就是讲所执行的SQL语句写到日志中,所以Slave 的 SQL线程才能读取。

配置思路(基于位置点的主从复制):
主从服务器
1、写配置文件。
主服务器
2、创建用户,分配权限。
从服务器
3、修改从服务器的Master信息。

再开始第一步之前,要先确定两个数据库的内容一致。
先将运行一段时间的主服务器全表上读锁,备份,然后在从服务器,也就是空库的服务器,恢复数据。这样就保证两个服务器的数据一致了。
主:

mysql >  flush tables with read lock;
//全表上锁,保证备份时,不会有不同的
[root@localhost ~]# mysqldump -u root -p --all-databases > /tmp/all.sql

将主服务的备份文件远程拷贝到从服务器:

[root@localhost ~]# scp /tmp/all.sql 172.16.12.15:/tmp/

从:

[root@localhost ~]# mysql -u root -p < /tmp/all.sql

1、主和从服务器的配置文件都要进行修改。
如下几行就是与复制相关的内容

relay-log       = /data/mysql/relay-log/slave_relay_bin   //这个是中继日志的位置
relay-log-index = slave_relay_bin.index    //中继日志的索引,就是告诉有多少个文件的。用处不大。
log-slave-updates    //这个是更新日志,在级联时有用,在下边详细说。
binlog_format   = row   //日志的记录模式,行模式
server-id       =  50   //服务器的ID。尽量别重复
log-bin         = /data/mysql/binlog/binlog    //二进制日志的位置
log-bin-index   = binlog.index    //二进制日志的索引
innodb_log_buffer_size  = 16M     //缓存的大小

log-slave-updates这个选项在两级,也就是AB,AABB,AA,ABBB时都没啥用,但是级联时有用,级联就是多级的,一个主,一个从,但是这个从服务器同时还是另外一个MySQL服务的主服务器。
而mysql的默认设置是,slave将master的日志获取回来并在本机执行的时候,这个执行过程是不记录到自己的二进制日志里的。简单来说,就是从服务器为了保证和主服务器保持一致,会执行和主服务器一样的SQL语句,但是从主服务获取到的SQL语句是不会记录到从服务器的二进制文件中。那么级联时从这个服务器,如果作为下边的服务器的主服务器时,最下边的从服务器,无法获取中间层从服务器的二进制文件,自然也就不能更新。
而开启了log-slave-updates这个选项,就可以将从Master获取的日志记录到自己的二进制日志中,可以让下层从服务器更新数据了。

然后重启MySQL服务。让配置文件修改生效。
bin包安装

[root@localhost ~]# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &

rpm安装

[root@localhost ~]# systemctl restart mysqld

2、主服务器创建用户。

主服务器要创建用户从服务器才能从这个用户访问到主服务器的日志。

mysql >  grant replication  slave,reload,super on *.* to slave@'172.16.12.15'  identified by '000000';
//replication  复制操作
//slave,reload,super  这个是3需要的权限。
//那个@后的IP写从服务器的,因为这个在主服务器上的用户是给从服务器用的,让从能访问主。
mysql > flush privileges;
//刷新权限列表

mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000027 |     1264 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

//File 就是上边说的主服务的二进制文件
//position  就是上边说的最新位置信息。

3、从服务器修改master信息。

mysql > change master to
	  > master_host='172.16.12.50',
	  > master_port=3306,
	  > master_user='slave',
	  > master_password='000000',
	  > master_log_file='binlog.000027',
	  > master_log_pos=1264;

这个一样只是好复制好修改
mysql> change master to master_host='192.168.0.7',master_port=3306,master_user='slave',master_password='000000',master_log_file='binlog.000007',master_log_pos=615;

主服务器IP,端口,分配的用户名,密码,二进制文件名,最新位置信息。后两个要填在主服务器中查到的。

然后从服务器启动slave

mysql > start slave;

查看slave状态

mysal > show slave status\G;

Relay_Log_File: slave_relay_bin.000002
                Relay_Log_Pos: 317
        Relay_Master_Log_File: binlog.000013
             Slave_IO_Running: Yes	<--
            Slave_SQL_Running: Yes	<--
            //看到这两个是yes就ok了。

配置思路(基于GTID的主从复制):

什么是GTID?
1、全局唯一,一个事务对应一个GTID
2、替代传统的binlog+pos复制;使用master_auto_position=1自动匹配GTID断点进行复制
3、MySQL5.6开始支持
4、在传统的主从复制中,slave端不用开启binlog;但是在GTID主从复制中,必须开启binlog
5、slave端在接受master的binlog时,会校验GTID值
6、为了保证主从数据的一致性,多线程同时执行一个GTID

工作原理:
1、master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
2、slave端的i/o 线程将变更的binlog,写入到本地的relay log中。
3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
5、如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。
6、在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描

基于GTID的主从复制有三个重点:
1、使用gtid模式,mysql的AB两端,必须是空库
架构部署初期。
因为日志会轮滚,如果之前有被轮滚掉的,必定配置失败。
没有被轮滚掉的日志,可以成功。
2、一个事务只有1个ID,约束不允许一条sql写入多个值。
3、如果你使用gtid模式,失败,想更改回位置点方式,需要将B库全部清空,重新连接。

配置思路:
1、主库从库,修改配置文件。

2、主库创建供从库使用的用户并分配权限。
3、从库修改master信息。

1、主和从库修改配置文件

server-id   = 51
//id修改
gtid_mode   = on
//gtid模式开启
enforce_gtid_consistency    = 1
//强制使用gtid

2、主库创建用户。

mysql > grant replication slave,reload,super on *.* to slave@'172.16.12.53' identified by '000000';
//同上,创建用户让从访问
mysql > flush privileges;
//刷新权限列表

3、从库修改master信息

mysql > change master to
	  > master_host='172.16.12.52',
	  > master_port=3306,
	  > master_user='slave',
	  > master_password='000000',
	  > master_auto_position=1;

前几项和前一种方法一样,最后一个看单词就能明白了,master_auto_position =1 自动位置信息开启。

然后就是启动。

mysql > start slave;

查看状态:

mysql > show slave status;

          Relay_Log_Pos: 862
        Relay_Master_Log_File: binlog.000011
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            //同样,这两个是yes就成功了。

测试:

在其中主服务器上CRUD操作,在从服务器能直接同步。

一个注意点:
在 /data/mysql/data目录下有个auto.cnf文件 ,这个文件就一行。

[root@localhost /]# cat /data/mysql/data/auto.cnf 
[auto]
server-uuid=e5f056af-05b9-11ea-9e51-000c293cc8a9

是这个UUID,这个是服务器的唯一表示,如果是复制的拷贝的环境,这个文件也是相同的,就不能用,需要将这个文件删除然后重启服务,重新生成这个文件,让它不一样,才能使用。

双主:

上文中说到的几种复制的模式还有AA,AABB,双主的问题。

这个其实很简单,就是将从变成主,主变成从,反向在做一次以上操作就好了。

比如我原来172.16.12.50是主,172.16.12.15是从做好了主从复制。现在将172.16.12.15作为主,172.16.12.50作为从再做一遍主从复制的操作,就是双主。

上边的第一步,修改配置文件,是主和从都这么改,就是为了这个原因,正常的话,从服务器不用开启二进制文件的功能,我也开启了,就是为了做双主。

单主的话,只能在主上做写操作,主从做读操作,如果在从上做了写操作,从就比主多数据了,主不能从从服务器获取数据。

而做好了双主之后,无论访问哪个服务器都可以同步到另一个。

注:mysql的权限:
一个大佬的详细讲解,非常牛啤,我就直接引用大佬的了。QAQ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值