1、基本介绍
这里主要介绍MySQL在复制过程中的内容。
首先介绍MySQL中的事物。这里指的就是一组原子性的SQL查询,亦或一个独立的步骤,但该步骤中包含很多SQL语句。数据库中的管理任务通产就是安装元组来划分,只有当一个元组完成/事物全部完成,此时SQL才会完全执行。这样做的目的是为了防止数据出现故障时,造成部分损坏数据的产生。
同时为了防止复制过程中的冲突,会产生两个锁---读锁定和写锁定。设置该锁的目的是为了防止同时对数据库某数据进行读写操作时,造成的数据混乱。
同时这里也需要满足数据库的四大特点:
- 原子性:事务包含的所有操作要么全部成功,要么全部失败回滚;成功必须要完全应用到数据库,失败则不能对数据库产生影响;
- 一致性:事务执行前和执行后必须处于一致性状态,
- 隔离性:当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不被其他事务的操作所干扰,多个并发事务之间要相互隔离;
- 持久性:一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便在数据库系统遇到故障的情况下也不会丢失事物的操作。
2、安装与基本配置
下载链接:https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.30-1.el7.x86_64.rpm-bundle.tar
官方文档:https://dev.mysql.com/doc/refman/5.7/en/replication.html
这里给出官方文档是为了方便查看更多操作,使操作更标准化。
安装步骤:
###安装步骤
#### 1 下载安装包,并解压
[root@server1 opt]# tar xf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
#### 2 去除不使用的包(下载时也可直接下载相应的包)
[root@server1 opt]# yum install -y mysql-*
#### 3 安全安全初始化
[root@server1 opt]# mysql_secure_installation
【说明】安全初始化前已经启动数据库,并且通过:cat /var/log/mysql.log | grep password 查看到临时密码。
所谓的复制,则是在两台主机见通信,故在server2(192.168.1.120)上也进行上述数据库操作。
3、异步复制
所谓的异步复制,与所谓的复制是不一样的。这里的复复制的不是数据,而是将主服务器中的操作步骤复制到从属服务器中。
3.1 基于二进制日志文件
具体过程是数据库执行事务并提交,然后将它们发送给第二数据库,以重新执行或应用。 它是无共享系统,默认情况下所有服务器均具有数据的完整副本。这里提交的文件也是二进制日志文件所以又称为二进制日志的主从复制。
工作流程如下:
-
当用户给主数据库写入时,主库上把数据的更改记录到二进制日志(Binary Log)中(这些记录被称为二进制日志事件);
-
备份时,从属数据库将主库上的日志复制到自己的中继(Relay Log)日志中;
-
备库读取中继日志中的事件,将其重放到备数据库之上。
###编写配置文件:/etc/mg.cfg
文件内容
...
29 log-bin=mysql-bin
30 server-id=1
...
配置完成后,重启数据库服务,进行相应配置:
数据库内配置如下:
##进行数据库设置
mysql> CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'Linux+755';
###创建用户(名字和网段),并设置密码
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
###用户授权
mysql> SHOW MASTER STATUS;
###查看二进制文件信息
在从属服务器上server2(192.168.1.120):
##编写配置文件:/etc/my.cfg
配置文件内容:
...
29 server-id=2
...
在从属数据库配置主节点的信息,并开启复制功能;
测试:
在server1上建立数据:
查看日志信息:
在server2上可直接查看:
3.2 基于GTID全局变量的主从复制
GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。而GTID (Global Transaction ID)是全局事务ID,当在主库上提交事务或者被从库应用时,可以定位和追踪每一个事务,对DBA来说意义就很大了,我们可以适当的解放出来,不用手工去可以找偏移量的值了,而是通过CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION=1的即可方便的搭建从库,在故障修复中也可以采用MASTER_AUTO_POSITION=‘X’的方式。
GTID是一种很好的分布式ID实践方式,通常来说,分布式ID有两个基本要求:1)全局唯一性;2)趋势递增。ID因为是全局唯一,所以在分布式环境中很容易识别,因为趋势递增,所以ID是具有相应的趋势规律,在必要的时候方便进行顺序提取,行业内适用较多的是基于Twitter的ID生成算法snowflake,所以换一个角度来理解GTID,其实是一种优雅的分布式设计。
配置服务:
server1节点:
###在配置文件/etc/my.cnf中开启gtid服务,配置如下:
...
31 gtid_mode=ON
32 enforce-gtid-consistency=ON
...
配置成功后,重启服务。
server2节点:
###修改配置文件,开启服务
....
gtid_mode=ON ##打开gtid
enforce-gtid-consistency=ON
....
进入数据库,修改主服务器的信息:这里首先关闭二进制存储配置,
开启服务,并查看服务是否成功。
测试:
主节点server1上插入数据:
从属节点server2上查看数据:
查看跟踪和执行的事务:
也可查看mysql中的gite_exexuted记录。
4、半异步复制
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
具体特性:
-
从库会在连接到主库时告诉主库,它是不是配置了半同步。
-
如果半同步复制在主库端是开启了的,并且至少有一个半同步复制的从库节点,那么此时主库的事务线程在提交时会被阻塞并等待,结果有两种可能,要么至少一个从库节点通知它已经收到了所有这个事务的Binlog事件,要么一直等待直到超过配置的某一个时间点为止,而此时,半同步复制将自动关闭,转换为异步复制。
-
从库节点只有在接收到某一个事务的所有Binlog,将其写入并Flush到Relay Log文件之后,才会通知对应主库上面的等待线程。
-
如果在等待过程中,等待时间已经超过了配置的超时时间,没有任何一个从节点通知当前事务,那么此时主库会自动转换为异步复制,当至少一个半同步从节点赶上来时,主库便会自动转换为半同步方式的复制。
-
半同步复制必须是在主库和从库两端都开启时才行,如果在主库上没打开,或者在主库上开启了而在从库上没有开启,主库都会使用异步方式复制。
其中有一个ACK对返回的消息进行确认。
服务配置:
因为该服务是通过插件完成的,所以要在主从服务器上均添加插件:
###主服务器添加的插件
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
###从属服务器添加的插件
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
#####分别查看是否安装成功
-> SELECT PLUGIN_NAME, PLUGIN_STATUS ##检测插件是否安好
-> FROM INFORMATION_SCHEMA.PLUGINS
-> WHERE PLUGIN_NAME LIKE '%semi%';
###主服务器启动插件
SET GLOBAL rpl_semi_sync_master_enabled = 1;
###从属服务器启动插件
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
#######配置完成后,重启从属服务器上的IO线程
-> STOP SLAVE IO_THREAD;
-> mysql> START SLAVE IO_THREAD;
-> mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';查看从服务器插件状态
######查看主服务的状态和ACK确认时间
###查看主服务器状态
-> SHOW STATUS LIKE 'rpl_semi_sync%';
###查看ACK确认时间
-> SHOW VARIABLES LIKE 'rpl_semi_sync%';
检查主服务器状态:
测试:两台均正常的情况下:
若从属宕机(或者关闭IO线程通道即可):
主数据库建立的信息,需要等待ACK返回确认,或者超时才能完成。
当再次启动时,数据会恢复:
5、组复制
组复制分单主模式和多主模式,mysql 的复制技术仅解决了数据同步的问题,如果 master 宕机,意味着数据库管理员需要介入,应用系统可能需要修改数据库连接地址或者重启才能实现。组复制在数据库层面上做到了,只要集群中大多数主机可用,则服务可用。
单主模型:从复制组众多个MYSQL节点中自动选举一个master节点,只有master节点可以写,其它节点自动设置为只读。当master节点故障时,会自动选举一个新的master节点,选举成功后,它将设置为可写,其它的slave将指向这个新的master。
多主模型:复制组中的任何一个节点都可以写,因此没有master和slave的概念,只要突然故障的节点的数量不太多这个多主模就能继续使用。
原理:
组复制由多个mysql服务器组成,并且组中的每一个mysql服务成员可以独立的执行事务。但是所有的读写事务只有在冲突检测成功后才会提交,只读事务不需要冲突检测,可以立即提交。
对于任何读写事务,提交操作并不是由始发服务单向决定的,而是由组来决定是否提交。
在始发mysql服务上,当事务准备好要提交时,该主机会广播写入值即已改变的行和对应的写入集及已更新的行的唯一标识符。然后会为该事务建立一个全局的顺序。最终,所有的server成员以相同的顺序接收同一组事务。所有的server成员以相同的顺序应用相同的更改,以保证组内一致
组复制的特点:
- 一致性:基于原生复制及 paxos 协议的组复制技术,并以插件的方式提供,提供一致数据安全保证;
- 容错性:只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制;
- 扩展性:节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息;
- 高灵活性:有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;多主模式下,所有 server 都可以同时处理更新操作。
使用条件:
- 只支持innodb存储引擎
- 每张表都需要有主键
- 只支持ipv4网络环境
- 要求高网络带宽(通常是千兆内网)和低网络延迟
组配置,因为组之间无主从之分,故在所有主机中均需进行如下配置:
####配置组复制,在/etc/my.cnf中进行如下配置
....
34 server_id=1 ##开启组复制
35 gtid_mode=ON
36 enforce_gtid_consistency=ON
37 master_info_repository=TABLE
38 relay_log_info_repository=TABLE
39 binlog_checksum=NONE
40 log_slave_updates=ON
41 log_bin=binlog
42 binlog_format=ROW
43 plugin_load_add='group_replication.so' ##组复制设置
44 transaction_write_set_extraction=XXHASH64
45 loose-group_replication_group_name="15ca0077-9bec-11ea-815a-000c2901473f"
##组的ID,在/var/lib/mysql/auto.cnf
46 loose-group_replication_start_on_boot=off
47 loose-group_replication_local_address= "192.168.1.110:33061"
48 loose-group_replication_group_seeds= "192.168.1.110:330611,192.168.1.120:330 61,192.168.1.130:33061" ##组ip
49 loose-group_replication_bootstrap_group=off
50 loose-group_replication_ip_whitelist="127.0.0.1,192.168.1.0/24"
51 loose-group_replication_enforce_update_everywhere_checks=ON
52 loose-group_replication_single_primary_mode=OFF
.....
【说明】配置解析可查看文章:https://www.cnblogs.com/love19791125/p/8176024.html
配置完成后,对数据库进行安全初始化,重新测试:
进入数据库,设置相应的参数可用户:
###在数据库中进行如下配置
##关闭二进制文件
mysql> SET SQL_LOG_BIN=0;
##创建授权用户
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'password';
##用户授权
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
##刷新授权表
mysql> FLUSH PRIVILEGES;
##开启二进制文件
mysql> SET SQL_LOG_BIN=1;
##更改用户的复制方式为组复制
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Linux+755' FOR CHANNEL 'group_replication_recovery';
##打开组复制参数
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
##启动组复制
mysql> START GROUP_REPLICATION;
##关闭组启动方式,防止生成不同的组名
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
##查看组复制的成员
mysql> SELECT * FROM performance_schema.replication_group_members;
关闭二进制文件时为了防止其他主机也同时生成,造成数据混乱。
在server2上进行如上配置:
###需要修改的为:
.....
32 server_id=2
.....
45 loose-group_replication_local_address= "192.168.1.120:33061"
.....
在数据库中执行:
###在数据库中进行如下配置
##关闭二进制文件
mysql> SET SQL_LOG_BIN=0;
##创建授权用户
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'password';
##用户授权
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
##刷新授权表
mysql> FLUSH PRIVILEGES;
##开启二进制文件
mysql> SET SQL_LOG_BIN=1;
##更改用户的复制方式为组复制
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Linux+755' FOR CHANNEL 'group_replication_recovery';
###强制加入表
set global group_replication_allow_local_disjoint_gtids_join=ON;
##启动组复制
mysql> START GROUP_REPLICATION;
##查看组复制的成员
mysql> SELECT * FROM performance_schema.replication_group_members;
测试:
在server1中创建表:
建立的数据在该组的集群中均可看到。
参考资料:
- https://www.cnblogs.com/caicz/p/10855605.html
- https://www.cnblogs.com/kevingrace/p/10228694.html
- https://blog.csdn.net/even160941/article/details/97624242
- https://blog.csdn.net/weixin_34248705/article/details/85133494