一、Mysql
1. Mysql的介绍
Mysql是一个关系型数据库管理系统,由瑞典MYSQL AB公司开发,目前属于Oracle旗下的产品。关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库。
2. Mysql复制的介绍
(1)异步复制(Asynchronous replication)
MySQL主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
(2)全同步复制(Fully synchronous replication)
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
(3)半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
3. Mysql中的线程介绍
(1)主节点 binary log dump 线程
当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。
(2)从节点I/O线程
当从节点上执行start slave命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。
(3)从节点SQL线程
SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。
二、Mysql安装
1. 下载软件,解开tar包
mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
tar xf mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
2. 删除不需要的包,安装要使用的包
rm -fr mysql-community-devel-5.7.24-1.el7.x86_64.rpm
mysql-community-embedded-5.7.24-1.el7.x86_64.rpm
mysql-community-embedded-compat-5.7.24-1.el7.x86_64.rpm
mysql-community-embedded-devel-5.7.24-1.el7.x86_64.rpm
mysql-community-minimal-debuginfo-5.7.24-1.el7.x86_64.rpm
mysql-community-server-minimal-5.7.24-1.el7.x86_64.rpm
mysql-community-test-5.7.24-1.el7.x86_64.rpm
yum install -y *.rpm
3. 修改配置文件
vim /etc/my.cnf
log-bin=mysql-bin #文档最后加,二进制日志复制,id号来区分主机
server-id =1
systemctl start mysqld
4. 使用随机密码,进行安全初始化
cat /var/log/mysqld.log | grep password
mysql_secure_installation (1个n,其余的都为y)
密码必须有字母、数字、特殊字符
5. 创建用户并授权
msql -uroot -p #登录数据库
CREATE USER 'repl'@'172.25.65.%' IDENTIFIED BY 'Jiang+123'; #创建用户
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.25.65.%'; #授权
flush privileges; #刷新授权表
show plugins; #查看密码设置插件
show master status; #查看主mysql的状态,从中获取日志文件和当前日志位置
6. 测试:测试创建的用户是否可以登录
mysql -h 172.25.65.1 -urepl -pJiang+123
三、基于二进制文件的主从复制
1. server2中将server1中的rpm包拷贝过来,并进行安装,初始化(server2和server1操作一致,在修改时注意配置文件中的id号)
scp server1:/root/*.rpm .
yum install -y *.rpm
vim /etc/my.cnf
server-id =2
systemctl start mysqld
cat /var/log/mysqld.log | grep password
mysql_secure_installation (1个n,其余均为y)
2. 登录数据库,设置从结点
注意:日志文件和日志文件开始的位置,必须在主数据库中查看,使用【show master status;】命令
mysql -uroot -pJiang+123
CHANGE MASTER TO
MASTER_HOST='172.25.65.1', #主节点
MASTER_USER='repl', #主节点中的用户
MASTER_PASSWORD='Jiang+123',
MASTER_LOG_FILE='mysql-bin.000002', #日志文件
MASTER_LOG_POS=1338; #日志文件开始的位置
start slave; #开启从节点
show slave status\G #查看主从复制状态
Slave_IO_Running: Yes #两个yes表示成功
Slave_SQL_Running: Yes
3. 测试主从复制
server1中操作(创建数据库和表)
注意:由于server1是主数据库,所以要在server1中写入数据,让server2这个从结点去复制
show databases; #查看数据库
create database westos; #创建数据库
use westos; #进入数据库
create table usertb ( #创建表
username varchar(10) not null,
password varchar(20) not null);
desc usertb; #查看表结构
insert into usertb values ('user1','123'); #插入
select * from usertb;
server2中操作(查询数据库和表信息)
select * from westos.usertb; #查询,观察是否对数据进行备份
四、基于gtid的主从复制
server1中开启gtid
vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=true
进入mysql库,通过show tables;查看是否有gtid_executed表
systemctl restart mysqld
server2中开启gtid和重新设置从结点
vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=true
systemctl restart mysqld
stop slave;
change master to master_host='172.25.65.1',master_user='repl',master_password='Jiang+123',master_auto_position=1;
start slave;
show slave status\G #必须为两个yes
测试是否实现主从复制
server1中插入信息
use westos
insert into usertb values ('user2','123');
insert into usertb values ('user3','123');
server2中查看是否同步
show slave status\G #查看跟踪的事务和已经复制过的事务
use mysql;
select * from mysql.gtid_executed; #可以查看到源uuid、开始和结束的事
其他:查看mysql的相关日志信息
cd /var/lib/mysql
mysqlbinlog mysql-bin.000002 #在mysql中的操作信息
cat auto.cnf #查看节点的UUID
cat relay-log.info #查看server2中的relay-log(中继日志),一般存放主mysql的日志文件及复制的位置
show variables like 'log_%'; #查看二进制日志(mysql语句)
五、半同步复制
server1中安装半同步插件
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SELECT PLUGIN_NAME, PLUGIN_STATUS #查询插件状态
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%semi%';
SET GLOBAL rpl_semi_sync_master_enabled=1; #激活插件
server2中安装插件
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_slave_enabled=1; #激活插件
STOP SLAVE IO_THREAD; #重启IO线程使半同步生效
START SLAVE IO_THREAD;
show slave status\G
查看插件的状态及主结点相关信息
SHOW VARIABLES LIKE 'rpl_semi_sync%'; #查看插件的状态
show status like '%rpl%'; #可以查看等待复制的客户端数
server1中
rpl_semi_sync中各部分的含义
(1)是否开启半同步(2)切换复制的timeout(3)用于开启半同步复制模式时的调试级别,默认是32(4)至少有N个slave接收到日志(5)是否允许master 每个事物提交后都要等待slave的receipt信号。默认为on(6)等待的point
server2中
个部分的含义(1)是否开启半同步(2)用于开启半同步复制模式时的调试级别,默认是32(3)控制stop slave 的执行时间,在重放一个大的事务的时候,突然执行stop slave,命令 stop slave会执行很久,这个时候可能产生死锁或阻塞,严重影响性能
测试半同步
server2中关闭从结点向主结点更新的线程
STOP SLAVE IO_THREAD; #关闭io线程
server1中写入数据,进行测试
use westos
insert into usertb values ('user4','123'); #等待10s后切换为异步复制
insert into usertb values ('user5','123'); #已经切换为异步复制模式
show status like '%rpl%';
等待10s才成功,因为上面超时时间是10s,10s后如果没有收到slave节点的返回,就会切换到异步复制,第二次插入已经切换到了异步复制模式,插入速度明显变快。查看rpl的状态,可以看到半同步已经关闭,且等待复制的事务数量为2个
server2中开启io线程,与主节点连接,进行更新
START SLAVE IO_THREAD; #开启io线程
show processlist; #输出结果显示了有哪些线程在运行
use westos;
select * from usertb;
六、组复制(全同步复制)
实验准备:三台虚拟机,均安装mysql相关的rpm包(172.25.65.1,172.25.65.2,172.25.65.3)
server1中编写配置文件,设置组复制的相关参数
注意:在做实验之前将uuid备份,如果使用新的uuid则会出现错误,uuid应该与组中任何一个成员的uuid不同
cd /var/lib/mysql
cat auto.cnf #查看uuid
vim /etc/my.cnf
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE #关闭binlog校验
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW #组复制依赖基于行的复制格式
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="0f86ed41-b216-11e9-9b0d-5254005f390e" #可以看/var/lib/mysql/auto.cnf
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="172.25.65.1:33061"
loose-group_replication_group_seeds="172.25.65.1:33061,172.25.65.2:33061,172.25.65.3:33061"
loose-group_replication_bootstrap_group=off #插件是否自动引导,这个选项一般都要off掉,只需要由发起组复制的节点开启,并只启动一次,如果是on,下次再启动时,会生成一个同名的组,可能会发生脑裂
loose-group_replication_ip_whitelist="127.0.0.1,172.25.65.0/24"
loose-group_replication_enforce_update_everywhere_checks=ON
loose-group_replication_single_primary_mode=OFF #后两行是开启多主模式的参数
rm -fr /var/lib/mysql/*
cat /var/log/mysqld.log | grep password #查看获得的随机密码
mysql -uroot -p
alter user root@localhost identified by 'Jiang+123'; #修改密码
关闭数据库,将之前的数据库信息清除
server1中创建可以复制数据的用户身份并授权,同时安装组复制插件
SET SQL_LOG_BIN=0; #关闭二进制日志,防止传到其他server上
CREATE USER rpl_user@'%' IDENTIFIED BY 'Jiang+123'; #创建用户
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; #授权
FLUSH PRIVILEGES; #刷新授权表
SET SQL_LOG_BIN=1; #开启二进制日志
CHANGE MASTER TO MASTER_USER='rpl_user',MASTER_PASSWORD='Jiang+123' FOR CHANNEL 'group_replication_recovery'; #改变主结点为该组中的任意成员
INSTALL PLUGIN group_replication SONAME 'group_replication.so'; #安装插件
在server1中发起组复制,注意发起组复制的参数,只能打开一次并且需要关闭,该结点打开后,其他结点不能再次打开,每一次打开都会生成一个组。
SET GLOBAL group_replication_bootstrap_group=ON; #组复制发起节点开启这个参数
START GROUP_REPLICATION; #开启组复制
SET GLOBAL group_replication_bootstrap_group=OFF; #关闭该参数,该参数只开启这一次
查看组成员,并且在server1的数据库中创建新的数据库和表
select * from performance_schema.replication_group_members; #查看组成员信息及状态
create database test;
use test;
create table t1 (c1 int primary key, c2 text not null);
insert into t1 values (1,'Luis');
select * from t1;
在server2中操作
vim /etc/my.cnf #将server1的配置文件复制过来,只需要该两个参数
server_id=2
loose-group_replication_local_address="172.25.65.2:33061"
systemctl stop mysqld
rm -fr *
cat /var/log/mysqld.log | grep password
alter user root@localhost identified by 'Jiang+123';
SET SQL_LOG_BIN=0;
CREATE USER rpl_user@'%' IDENTIFIED BY 'Jiang+123';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='rpl_user',MASTER_PASSWORD='Jiang+123' FOR CHANNEL 'group_replication_recovery';
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
set global group_replication_allow_local_disjoint_gtids_join=on; #强制加入该组(server1中有数据导致环境不纯净)
START GROUP_REPLICATION; #开启组复制
注意:server1中发起组复制的参数,在server2中不能使用,如果开启该参数,会创建一个相同的组,组中只有一个成员就是自己本身,显然这不是我们要实现的效果
在server1中查看组成员是否添加成功
select * from performance_schema.replication_group_members;
server3中
由于server2和server3步骤一致,这里的修改过程参照server2的,只需要修改/etc/my.cnf中的两个参数,id号和本机地址。由于server3是一个全新的环境,没有安装mysql,在实验前需要安装mysql
scp server1:/home/*.rpm
yum install -y *.rpm
vim /etc/my.cnf #将server1的配置文件复制过来,只需要该两个参数
server_id=3
loose-group_replication_local_address="172.25.65.3:33061"
systemctl start mysqld
cat /var/log/mysqld.log | grep password
mysql -uroot -p
alter user root@localhost identified by 'Jiang+123';
在server1中查看所有组成员是否添加成功
测试效果:在任意一台mysql中插入数据,其他组成员中会立即备份,从而实现了组复制