二、实操篇
1. 配置master主服务
第1步:修改my.cnf配置文件
首先,配置主节点的mysql配置文件: /etc/my.cnf
这一步需要对master进行配置,主要是需要打开binlog日志,以及指定severId。
[mysqld]
#服务器ID
server-id=1
#开启binlog
log-bin=/logs/mysql-bin
# log_bin-index是Binlog日志文件,记录log-bin日志的路径,默认是log-bin+index后缀(Eg:/logs/mysql-bin.index)[可选]
log_bin-index=mysql-bin.index
# binlog刷盘策略
sync_binlog=1
# 只保留7天的二进制日志,以防磁盘被日志占满[可选]
expire-logs-days=7
- server-id:服务节点的唯一标识。需要给集群中的每个服务分配一个单独的ID。
- og_bin:打开Binlog日志记录,并指定文件名。
- sync_binlog参数:
0 :存储引擎不进行binlog的刷新到磁盘,而由操作系统的文件系统控制缓存刷新。
1:每提交一次事务,存储引擎调用文件系统的sync操作进行一次缓存的刷新,这种方式最安全,但性能较低。
n:当提交的日志组=n时,存储引擎调用文件系统的sync操作进行一次缓存的刷新。
温馨提示:
sync_binlog=0
或sync_binlog大于1
,事务被提交,而尚未同步到磁盘。因此,在电源故障或操作系统崩溃时有可能服务器已承诺尚未同步一些事务到二进制日志。因此它是不可能执行例行程序恢复这些事务,他们将会丢失二进制日志。
第2步:重启 mysql 服务
service mysqld restart
第3步:主机给从机授权备份权限
注意:先要登录到MySQL命令客户端
create user '从机MySQL用户名'@'从机IP' identified by '设置密码';
GRANT REPLICATION SLAVE ON *.* TO '从机MySQL用户名'@'从机IP';
mysql5.7对密码的强度是有要求的,必须是字母+数字+符号组成的,可以使用如下方法调整密码强度
-- 设置密码长度最低位数 set global validate_password_length=4; -- 设置密码强度级别 mysql> set global validate_password_policy=0;`
validate_password_policy 有以下取值:
Policy Tests Performe 0 or LOW Length 1 or MEDIUM numeric, lowercase/uppercase, and special characters > 2 or STRONG Length; numeric, lowercase/uppercase, and special characters 默认是1,即MEDIUM,所以刚开始设置的密码必须符合长度,且必须含有数字,小写或大写字母,特殊字符。
第4步:刷新权限
flush privileges;
第5步:查询master的状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 1584 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
2. 配置slave从服务
第1步:修改my.conf配置文件
[mysqld]
# 服务器ID(主库和从库需要不一致)
server_id=2
# 开启中继日志(并指定日志路径)
relay-log=/logs/slave-relay-bin
# relay-log-index是relay-log日志文件,专门记录relay-log日志的路径,默认是relay-log+index后缀(Eg:/logs/logs/slave-relay-bin.index)
relay-log-index=/logs/slave-relay-bin.index
# 开启自动清空不再需要中继日志(非必选项)
relay_log_purge=1
# `log_slave_updates` 作用如下(默认关闭)
# 1. 从库只开启log-bin功能,不添加log_slave_updates参数,从库从主库复制的数据不会写入log-bin日志文件里。
# 2、直接向从库写入数据时,是会写入log-bin日志的。
# 3、开启log_slave_updates参数后,从库从主库复制的数据会写入log-bin日志文件里。这也是该参数的功能
##注意:从节点配置文件加入log_slave_updates=1,同步异常慢
# log_slave_updates=1
第2步:删除UUID文件
如果出现以下错误:
Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
原因:因为是mysql是克隆的系统,所以mysql的uuid是一样的,所以需要修改。
解决方法:
# 删除/var/lib/mysql/auto.cnf文件,重新启动MySQL服务。
rm -rf /var/lib/mysql/auto.cnf
service mysqld restart
第3步:登录到Slave MySQL进行配置
mysql> change master to
master_host='172.18.159.1',
master_port=3306,
master_user='mysql_master',
master_password='123456',
master_log_file='mysql-bin.000001',
master_log_pos=1584,
MASTER_AUTO_POSITION=0,
GET_MASTER_PUBLIC_KEY = 1
注意:
语句中间不要断开。
master_port为mysql服务器端口号(无引号)
master_user为执行同步操作的数据库账户,“410”无单引号(此处的410就是show master status 中看到的position的值
这里的mysql-bin.000001就是file对应的值)。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ik5HaSVI-1660577096437)(.assets/image-20220802225659395.png)]
MASTER_AUTO_POSITION:是否开启GTID事物。(0-关闭;1-开启;默认:0)
GET_MASTER_PUBLIC_KEY=1:是因为开启主从复制的时候可能会报出下方的异常。原因是mysql8默认使用插件caching_sha2_password,有些client连接报这个错误,需要拿到server的public key来加密password。(mysql8以下,可以忽略)
ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
第4步:开启Slave
mysql>start slave;
第5步:检查Slave状态
mysql>show slave status \G
……………………(省略部分)
Slave_IO_Running: Yes //此状态必须YES
Slave_SQL_Running: Yes //此状态必须YES
……………………(省略部分)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bfJoA9QX-1660577096439)(.assets/image-20220802230412566.png)]
注意:
- 红色方框的Slave_IO_Runcation和Slave_SQL_Runcation为YES状态,即slave进程正常运行。否则为错误的状态(如:其中一个NO均属错误)。
- 蓝色方框两个属性,与主节点保持一致,就表示这个主从同步搭建是成功。
- 从这个指令的结果能够看到,有很多**
Replicate_
开头的属性,这些属性指定了两个服务之间要同步哪些数据库、哪些表的配置。如果全都没有进行配置(如上图所示Replicate_
**都是空值),就标识是全库进行同步。
3. 主从集群测试
1) 看数据库
show databases;
2)在Master执行DDL语句
-- 创建库
create databese syncdemo;
use syncdemo;
-- 创建表
create table demoTable(id int not null);
-- 插入数据
insert into demoTable value(1);
3) 结果
从上面的实验过程看到,我们在主服务中进行的数据操作,就都已经同步到了从服务上。我们一个主从集群就搭建完成了。
4. 集群搭建扩展
1)部分库同步
实际环境中,一般并不需要针对全库做备份,而只需要对一些特别重要的库或者表来进行同步。下面我们进行部分库进行同步。
第一步:修改Master服务的my.cnf配置文件
#需要同步的二进制数据库名(设置多个库,需要配置多个binlog-do-db)
binlog-do-db=syncdemo
binlog-do-db=syncdemo2
#不备份的数据库
binlog-ignore-db=information_schema
binlog-ignore-db=performation_schema
binlog-ignore-db=sys
第二步:修改Slave服务的my.cnf配置文件
#如果salve库名称与master库名相同,使用本配置
replicate-do-db=syncdemo
#如果master库名[syncdemo]与salve库名[syncdemo3]不同,使用以下配置[需要做映射]
## replicate-rewrite-db = syncdemo -> syncdemo3
#指定需要同步的表。(默认同步所有的表)
## replicate-wild-do-table=syncdemo3.t_dict
## replicate-wild-do-table=syncdemo3.t_num
#设置某个库不同步
## replicate-wild-ignore-table=mysql.%
#设置某个表不同步
## replicate-wild-ignore-table=mysql.user
第三步:重启Master和Slave服务
service mysql restart
第四步:查询 Master和Slave的状态
-- Master状态
show master status;
-- Slave状态
show slave status;
2)读写分离配置
目前我们的这个MySQL主从集群是单向的,也就是只能从主服务同步到从服务,而从服务的数据表更是无法同步到主服务的。
在MySQL主从架构中,是需要严格限制从服务的数据写入的,一旦从服务有数据写入,就会造成数据不一致。并且从服务在执行事务期间还很容易造成数据同步失败。 如果需要限制用户写数据,我们可以在从服务中将read_only参数的值设为1
,这样就可以限制用户写入数据
-- 设置Mysql服务器为只读模式
set global read_only=1;
read_only这个属性需要注意两个点:
1)read_only=1设置的只读模式,不会影响slave同步复制的功能。
在MySQL slave库中设定了read_only=1后,通过 “show slave status\G” 命令查看salve状态,可以看到salve仍然会读取master上的日志,并且在slave库中应用日志,保证主从数据库同步一致;2)read_only=1设置的只读模式, 限定的是普通用户进行数据修改的操作,但不会限定具有super权限的用户的数据修改操作。
在MySQL中设置read_only=1
后,普通的应用用户进行insert、update、delete等会产生数据变化的DML操作时,都会报出数据库处于只读模式不能发生数据变化的错误,但具有super权限的用户,例如在本地或远程通过root用户登录到数据库,还是可以进行数据变化的DML操作;如果需要限定super权限的用户写数据
- 可以设置
super_read_only=0
。- 如果要想连super权限用户的写操作也禁止,就使用"flush tables with read lock;",这样设置也会阻止主从同步复制!
所以,在这种架构下,为了保证数据一致,通常会需要保证数据只在主服务上写,而从服务只进行数据读取。这个功能,就是大名鼎鼎的读写分离。但是这里要注意下,mysql主从本身是无法提供读写分离的服务,需要由业务自己来实现。这也是我们后面要学的ShardingSphere的一个重要功能。
5. 主从集群失败原因
主从架构是有可能失败的,如果在slave从服务上查看slave状态,发现Slave_SQL_Running=no,就表示主从同步失败了。失败原因如下:
-
从数据库上进行了写操作,与同步过来的SQL操作冲突了。
-- 解决方法:可以按照以下方式重启主从同步 mysql> stop slave ; mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1; mysql> start slave ;
-
slave从服务重启后有事务回滚了。
-- 解决方法:重新记录主节点的binlog文件消息 -- 但是这种方式要注意binlog的文件和位置,如果修改后和之前的同步接不上,那就会丢失部分数据。所以不太常用。 mysql> stop slave ; mysql> change master to ..... mysql> start slave ;