主从复制(也称 AB 复制)允许将来自一个MySQL数据库服务器(主服务器)的数据复制到一个或多个MySQL数据库服务器(从服务器)。
MySQL之间数据复制的基础是二进制日志文件(binary log file)。一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。
mysql的主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库,主数据库一般是实时的业务数据操作,从数据库常用的读取为主。
优点主要有
1,可以作为备用数据库进行操作,当主数据库出现故障之后,从数据库可以替代主数据库继续工作,不影响业务流程
2,读写分离,将读和写应用在不同的数据库与服务器上。一般读写的数据库环境配置为,一个写入的数据库,一个或多个读的数据库,各个数据库分别位于不同的服务器上,充分利用服务器性能和数据库性能;当然,其中会涉及到如何保证读写数据库的数据一致,这个就可以利用主从复制技术来完成。
3,吞吐量较大,业务的查询较多,并发与负载较大。
异步复制是MySQL默认的复制方式,原理是在主库写入binlog日志后,就可以直接成功返回客户端,不用等待binlog日志传递给从库的过程。相对来说会更快,但是一旦主库发生宕机,就有可能发生数据丢失。
主从复制,默认是通过pos复制(postion),就是说在日志文档里,将用户进行的每一项操作都进行编号(pos),每一个event都有一个起始编号,一个终止编号,我们在配置主从复制时从节点时,要输入master的log_pos值就是这个原因,要求它从哪个pos开始同步数据库里的数据,这也是传统复制技术,以后就自己去读取上一次同步到哪一块,接着同步.
MySQL5.6增加了GTID复制,GTID就是类似于pos的一个作用,不过它是整个mysql复制架构全局通用的,就是说在这整个mysql冗余架构中,它们的日志文件里事件的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的日志文件,继续同步。
主机名 | ip | 服务 |
---|---|---|
server1 | 172.25.1.1 | 数据库master |
server2 | 172.25.1.2 | 数据库slave |
foundation1.ilt.example.com | 172.25.1.250 | 客户端 |
server1要关闭防火墙
master节点上:
步骤一:下载mysql社区版服务器安装包
下载地址:mysql-community
步骤二:安装软件包
yum install -y mysql-community-client.x86_64 mysql-community-common.x86_64 mysql-community-libs.x86_64 mysql-community-libs-compat.x86_64 mysql-community-server.x86_64
vim /etc/my.cnf
log-bin=mysql-bin #在文件末尾写
server-id=1 #(每个节点的序号是唯一的)
systemctl start mysqld
开启服务之后会生成一个临时密码,使用临时密码进行数据库安全初始化
cat /var/log/mysqld.log | grep password #查看临时密码
安全初始化
安全初始化登陆的时候使用的是临时密码,接下来要自己设置数据库的密码,这个密码必须有特殊字符,英文字母的大小写还有数字
mysql_secure_installation
步骤一:下载mysql社区版服务器安装包
下载地址:mysql-community
步骤二:安装软件包
yum install -y mysql-community-client.x86_64 mysql-community-common.x86_64 mysql-community-libs.x86_64 mysql-community-libs-compat.x86_64 mysql-community-server.x86_64
vim /etc/my.cnf
server-id=2
systemctl start mysqld
cat /var/log/mysqld.log | grep password
mysql_secure_installation
创建并授权用来做复制的用户
在Master的数据库中建立一个备份帐户:每个slave使用标准的MySQL用户名和密码连接master。进行复制操作的用户会授予REPLICATION SLAVE权限。用户名的密码都会存储在文本文件master.info中
mysql> CREATE USER 'repl'@'172.25.1.%' IDENTIFIED BY 'Westos+007'; ## 创建用户,可以使用此用户远程登录数据库;
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.25.1.%'; #授权为可以复制master节点数据的slave节点
mysql> flush privileges; #刷新授权表
mysql> show plugins;
##查看插件,因为有密码插件,所以密码必须设置为复杂的
mysql> show master status;
##查看master状态
参数 | 解释 |
---|---|
REPLICATION | 表示复制的权限 |
* .* | 表示对所有库的所有表都授权 |
repl | 用户名 |
‘172.25.12.%’ | 授权172.25.12网段的所有数据库节点都可以同步(复制) |
mysql -h 172.25.1.1 -urepl -pWestos+007
在slave上:
配置master信息
mysql> change master to master_host='172.25.1.1', ##在这个slave节点上面设置管理它的master节点主机信息
-> master_user='repl', ##用户
-> master_password='Westos+007',
-> master_log_file='mysql-bin.000001',
-> master_log_pos=1322; #复制点,从master上查看
mysql> start slave; ##开启本节点的slave
mysql> show slave status\G ##查看主从复制状态
Slave_IO_Running: Yes Slave_SQL_Running: Yes 这两个参数是Yes,表示成功。
因为对于slave节点来说,io线程和sql线程是最重要的两个线程。只有当io线程和sql线程都开启的时候,slave节点才可以正常复制master节点的数据
测试主从同步是否生效
注意:写操作只能在master结点上,读操作在slave节点上
在master创建新数据:
mysql> create database yan; #创建库
mysql> use yan;
mysql> create table test ( #创建表
-> name varchar(10) not null,
-> age int(10) not null);
mysql> desc test; #查看表的属性
mysql> insert into test values ('user1','18'); #插入数据
mysql> select * from test; #查表
此实验是基于position的主从复制的基础上进行的
在master(server1)上:
步骤一:修改配置文件加入开启gtid的信息
vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=true
systemctl restart mysqld
补充:查看之前在数据库中的操作方法:
cd /var/lib/mysql
mysqlbinlog mysql-bin.000002
查看此节点的uuid:
cd /var/lib/mysql
cat auto.cnf
在slave(server2)上:
步骤一:开启gtid信息
vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=true
systemctl restart mysqld
步骤三:登陆数据库启用gtid
mysql -uroot -pWestos+007
mysql> stop slave;
mysql> CHANGE MASTER TO
-> MASTER_HOST = '172.25.1.1',
-> MASTER_USER = 'repl',
-> MASTER_PASSWORD = 'Westos+007',
-> MASTER_AUTO_POSITION = 1;
mysql> start slave;
mysql> show slave status\G
此时能查看到这两项
Retrieved_Gtid_Set:
Executed_Gtid_Set:
测试:
在master(server1)上写入信息:
mysql> show databases;
mysql> use yan;
mysql> show tables;
mysql> select * from test;
mysql> insert into test values ('user2','20');
mysql> select * from test;
mysql> show master status;
615bf859-4890-11ea-905f-525400867156是主库的server-uuid
1代表主库产生了1个事务
在slave(server2)上查看:
发现这两个参数 Retrieved_Gtid_Set: 和Executed_Gtid_Set: 由值了,从1位置开始复制
show slave status\G
再查看gtid模式复制的起始和结束位置:
mysql> use mysql;
mysql> select * from gtid_executed;