目录
我们先来最重要的,代码部分,先来明白主从怎么搭建。
首先我们需要准备两台服务器,docker,虚拟机都是可以的。但是使用虚拟机可能会出现,关机再开启后从库连接不上主库的问题。小编这里使用了自己的线上服务器来搭建。
主库搭建
进入到mysql的配置文件,在 [mysqld] 下面加入下面这串代码,然后重载我们的mysql配置让其生效(/etc/my.cnf)
#主服务器唯一ID
server-id=1
#启用二进制日志
log-bin=mysql-bin
#设置logbin格式
binlog_format=STATEMENT
# 设置不要复制的数据库,可以设置多个
binlog-ignore-db=mysql
#设置需要同步的数据库(未创建的数据库)
binlog-do-db=table1
#binlog-do-db设置后,可以不设置binlog-ignore-db
#重载mysql配置
service mysqld restart
然后我们进入mysql,为我们的从服务器创建远程连接,完成后以防万一,我们可以查看一下是否创建OK
#创建远程连接账号密码
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '111222';
#刷新mysql系统权限相关表
flush privileges;
#查看是否建立完成
select user from mysql.user where user='slave';
这一切都完成后,我们主库的配置就完成了,我们查看一下master的状态,这里面的内容,我们在从库连接时需要使用
- File:binlog日志的名字
- Position :接入点
- Binlog_Do_DB :需要复制的数据库
- Binlog_Ignore_DB :不需要复制的数据库
- Executed_Gtid_Set:写入binlog日志的事务产生的Gtid的集合
show master status;
从库搭建
同样的,我们打开mysql的配置文件,在 [mysqld] 下添加下面的代码 ,重载生效(/etc/my.cnf)
#主服务器唯一ID
server-id=2
#启用中继日志
relay-log=mysql-relay
#启用二进制日志
log-bin=mysql-bin
#重载mysql配置
service mysqld restart
然后我们进入到mysql中,连接我们的主库服务器,返回OK成功,如果从库曾配置过主从,我们需要先重启服务再进行配置
#停止从服务
stop slave;
#重置master
reset master;
CHANGE MASTER TO MASTER_HOST='主服务器IP地址',
MASTER_USER='远程连接账号',
MASTER_PASSWORD='远程连接密码',
MASTER_LOG_FILE='主库binlog日志名称',
MASTER_LOG_POS=主库接入点;
然后我们启动从服务,让主从生效,然后我们查看一下slave状态,\G的目的是为了让内容格式化输出,因为内容较多,格式化输出会更清晰的看到
#启动从服务
start slave;
#查看slave状态
show slave status\G
我们可以看到,IO线程和SQL线程都是YES状态,表示主从搭建成功,接下来就可以尝试再主库进行写的操作然后在从库查找啦。
这里呢,小编总结了一下搭建过程中的报错,mysql的主从整体还是比较简单的,容易错的点只有两个:
- 1. 远程连接不上主服务器,这里首先确保账号密码的正确,如果正确,一般就是主服务器的mysql端口号3306没有开启,线上服务器可以去服务器页面防火墙里配置规则,虚拟机或者别的可以手动打开
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
- 2. 依然是连接不上的问题,如果端口号也开启了,就可以去主库里看一下主库的host权限是否允许远程连接,如果查看的权限列表中没有%,那就证明无法通过远程连接到这个库。可以执行修改权限,然后重载,这样就可以连接了
use mysql;
#查看host权限
select host from user where User='root';
#修改权限
update user set host='%' where Host='localhost';
#重载
flush privileges;
解决完这些,基本上就可以连接上主库了,如果有别的报错,可以留言给我,也可以复制报错内容去搜索。
到这里呢,我们的主从就搭建好了!但是也只是搭建好了,我们在做每一个功能的时候呢,都应该明白为什么要使用,使用了有什么好处等等,这样我们的思路才会清晰,才能有更深入的理解。所以,我们接下来就来讲解一下
什么是MySQL主从?
mysql主从就是说,使用多台mysql服务器,实现对于数据的读写分离,分担单台mysql服务器的压力,使用一台服务器作为mysql主库,在这台服务器上实现对数据的写的操作,然后使用一台或多台服务器作为mysql从库,来实现对数据的读的操作
为什么要使用MySQL主从?
我们都知道mysql是一个关系型数据库,用来存储我们的数据,那么就会有对于某一张表的curd,当我们的访问量和操作量 都比较大时,我们就有可能出现读写冲突,或者压力过大等问题。所以我们采用主从的方式来将数据的读写操作分离,一方面防止读写冲突,另一方面也能减轻单台mysql的压力,提高系统的扩展性和可用性。
MySQL主从的实现原理
- 当我们在mysql主库上进行写的操作时,主库会将操作进行备份,存储到二进制日志binlog中
- 由从库的I/O线程来读取binlog日志的内容,将主库中写的操作读取到从库并转存到从库的中继日志relaylog中
- 从库通过SQL线程将relaylog中的内容进行读取并写入库中,实现主从数据同步
MySQL主从数据一致性问题
首先,我们先来了解为什么会出现一致性问题,我总结了以下几点
- 主从服务器的性能差距过大,一般主库的性能都是没有问题的,也就是说从库的性能太差,读取日志时发生问题而导致数据不一致
- 从库数量不合理,有的主从搭建好后从库数量过少,在大量数据的写入时,从库的同步压力过大导致从库出现问题,亦或者说从库数量过多,在同步数据时也会造成一定量的数据不一致,一般3 ~ 5台从库即可
- 大事务的执行,一条事务执行的时间过长,导致其他事务阻塞,binlog日志写入不一致等问题发生
- mysql自身版本过低,低版本的mysql不支持并发,而在并发场景时就有可能造成数据不一致问题
- 还有就是网络问题,一般来说也不会发生
具体的解决办法呢有三种
- 保证主从库的性能一致或者说差距较小
- 在主库中存在一个线程,是专门用来维持主从库的长链接的,这个可以用来保证数据一致性,所以要保证主库的性能不能过低
- 另外一个是binlog日志的格式,binlog日志存在三种格式,这个可以在sql配置文件中配置,上面搭建主从中有提到
- 第一种是statement,这是binlog的默认格式,它是将原生的sql语句存储进来,然后提供给从库,由于他直接记录了sql语句,自然也会提高很多性能,但是当我们数据库存在多条索引时,我们可能无法保证主从库对于同一条语句执行同一个索引,那么在同步数据时就有可能造成数据不一致
- 第二种是row,row是记录了两个事件(event):table_map和delete_rows,table_map是记录要操作的表,delete_rows是记录行为,记录每一行要修改的细节,这样就基本不会出现数据不一致的问题,但当修改或删除的数据量特别大时,row格式的binlog会很占空间,造成内存上的消耗
- 第三种是mixed,mixed相当于是前两者的折中版,他会对每一条记录的sql进行判断,如果是一般的sql,就使用statement格式的binlog,如果觉得statement处理不好,便会使用row,其实它本身并没有什么格式,只是在每次记录前进行判断,区别使用上面两种格式
其实在新版本的mysql中对row格式进行了优化,与其说是优化,更像是将mixed格式赋予进了row中,新版本的row格式会判断sql语句,如果涉及到整表改动或者大量数据的改动时,会使用statement来进行处理,提高效率,一般的update,delete依然使用row来记录变更细节。
这一版关于mysql主从的就到此结束了,希望每一个程序员都不只是敲代码。