Mysql-主从-主主(主备,双写)之(Docker版)

x33g5p2x  于2022-02-28 转载在 Mysql  
字(4.3k)|赞(0)|评价(0)|浏览(385)

介绍

当单台 MYSQL 服务器无法满足当前网站流量时的优化方案。需要搭建 mysql 集群技术。
复制方式:

  1. 主–从复制(读写分离)
  2. 主–主复制 (都可进行读写)
  3. 半同步复制

复制原理:
Mysql 中有一种日志叫做 bin 日志(二进制日志)。这个日志会记录下所有修改了数据库的SQL 语句(insert,update,delete,create/alter/drop table, grant 等等)。
主从复制的原理其实就是把主服务器上的 bin 日志复制到从服务器上执行一遍,这样从服务器上的数据就和主服务器上的数据相同了。

复制过程:

  1. 主节点必须启用二进制日志,记录任何修改了数据库数据的事件。
  2. 从节点开启一个线程(I/O Thread)把自己扮演成 mysql 的客户端,通过 mysql 协议,请求主节点的二进制日志文件中的事件
  3. 主节点启动一个线程(dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主节点就会从第一个日志文件中的第一个事件一个一个发送给从节点。
  4. 从节点接收到主节点发送过来的数据把它放置到中继日志(Relay log)文件中。并记录该次请求到主节点的具体哪一个二进制日志文件内部的哪一个位置(主节点中的二进制文件会有多个,在后面详细讲解)。
  5. 从节点启动另外一个线程(sql Thread ),把 Relay log 中的事件读取出来,并在本地再执行一次。

主–从配置演示:

虽然我这里使用的是docker方式,但是普通模式的mysql一样的操作

环境:

  • 主节点:192.168.0.196
  • 从节点:192.168.0.198
  • mysql版本:mysql8.0.16
  • linux:centos8
  • docekr: 20.10.8

主节点

进入mysql容器里

docker exec -it mysql8.0.16 /bin/bash

肯能没有vi命令这个自行安装

vi /etc/mysql/my.cnf

server_id=1
log_bin=master_log

退出docker 容器

exit

重启MySql (dcoekr)

docker restart  mysql8.0.16

然后在进入mysql容器里,之后连接mysql

mysql -u root -p

创建子节点连接主节点的账户

create user 'myslave'@'192.168.0.196' identified by 'myslave';
GRANT ALL ON *.* TO 'myslave'@'192.168.0.196';
flush privileges;

然后查看状态

show master status;

注意: 上面的File 和Position后面需要用到

查询server_id

show variables like 'server_id';

从节点

进入mysql容器里

docker exec -it mysql8.0.16 /bin/bash

修改配置

vi /etc/mysql/my.cnf

server_id=2

重启MySql (dcoekr)

docker restart  mysql8.0.16

然后在进入mysql容器里,之后连接mysql

mysql -u root -p

然后先关闭子节点同步,然后添加主节点配置

stop slave

添加主节点配置

CHANGE MASTER TO
MASTER_HOST='192.168.42.146',
MASTER_USER='myslave',
MASTER_PASSWORD='myslave',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=3796;

注意:MASTER_LOG_FILE 为上图查询出来的,MASTER_LOG_POS 为上图的 position 查出来的

启动子节点同步

start slave;

在slave上查看主从同步状态

show slave status\G;

开启主从之后,如果状态如上图所示,那么说明主从信息就已经配置好了,

mysql是虚拟机克隆的话那么会报错
The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be diff

解决办法: mv /usr/mysql/data/auto.cnf /usr/mysql/data/auto.cnf.bk 然后重启mysql

测试同步情况

主主配置演示:

环境:

节点1:
主节点:192.168.0.196 server-id=1
从节点:192.168.0.197 server-id=2
节点2:
主节点:192.168.0.198 server-id=3
从节点:192.168.0.199 server-id=4
注意: 所有节点的server-id不能重复,包括子节点,

  • mysql版本:mysql8.0.16
  • linux:centos8
  • docekr: 20.10.8

假设我们已经搭建好了2个主从节点了,那么此刻有两种模式提供选择

  1. 主备(当主节点宕机后,可以及时切换到备用节点)
  2. 双写(就是2个节点任意一个节点进行写的操作都会相互同步数据)

双写的问题:

就是两台M节点都要进行写入,网上都说调整auto_increment_increment和offset那两个参数可以达到双写不冲突的作用,但是这个做法有前提条件的,

  1. 主键必须是自增列
  2. 必须只有insert操作,如果一个事务中有insert又有update,那么双写是不行的,会有问题,
  3. 更何况还有唯一索引的问题。

那么有解决双写的问题吗?,当然有利于分库分表然利于业务逻辑进行关联就行了.

修改双主的配置文件

进入docker ->mysql里->vi /etc/mysql/my.cnf

第一个主(192.168.0.196)

#任意自然数,保证两台MySQL主机不重复
server-id=1  
#开启二进制日志
log-bin=mysql-bin   
#步进值auto_imcrement。一般有n台主MySQL就填n
auto_increment_increment=2   
#起始值。一般填第n台主MySQL。此时为第一台主MySQL
auto_increment_offset=1

配置完毕重启mysql

第二个主(192.168.0.198)

#任意自然数,保证两台MySQL主机不重复
server-id=2  
#开启二进制日志
log-bin=mysql-bin   
#步进值auto_imcrement。一般有n台主MySQL就填n
auto_increment_increment=2   
#起始值。一般填第n台主MySQL。
auto_increment_offset=2

配置完毕重启mysql

查询双主的bin文件信息

进入docker ->mysql里

SHOW MASTER STATUS;

创建登录用户

在第一个主节点(192.168.0.196) 里创建账号用于第二个主节点(192.168.0.198)登录使用

create user 'myMaster1'@'192.168.0.198' identified by 'myMaster1';
GRANT ALL ON *.* TO 'myMaster1'@'192.168.0.198';
flush privileges;

'myMaster1'@'192.168.0.198' 这句话的意思就是只能是192.168.0.198这个ip通过myMaster1账户才能登录此mysql

在第二个主节点(192.168.0.198)里创建账号用于第一个主节点(192.168.0.196)登录使用

create user 'myMaster2'@'192.168.0.196' identified by 'myMaster2';
GRANT ALL ON *.* TO 'myMaster2'@'192.168.0.196';
flush privileges;

双主(主备)

在第二个节点(192.168.0.198)进行下面操作,将第二个主节点作为子节点,关联到第一个主节点中进行数据同步
注意: LOG_FILEMASTER_LOG_POS填写第一个主节点查询出来的bin文件信息

# 先关闭子同步
stop slave;
# 在配置从子同步
CHANGE MASTER TO MASTER_HOST='192.168.0.196',
MASTER_USER='myMaster1',
MASTER_PASSWORD='myMaster1',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=1129;
# 打开子同步
start slave;
# 查看状态
show slave status\G;

看到上面两个yes那么就代表配置成功了,我们可以在主节点数据库操作看看子节点变化没

注意: 不能在子节点进行操作,否则会导致同步失败

开启主备后我们还需要使用keepalived或者haproxy来实现高可用才行…

双主(双写)

在主备的基础上双向开启同步就行了,在上面主备中我们已经完成了第二个主节点监听第一个主节点的同步了,那么我们只需要将第一个主节点监听第二个主节点,这样就形成双向通道了

在第一个节点(192.168.0.196)进行下面操作,将第一个主节点作为子节点,关联到第二个主节点中进行数据同步
注意: LOG_FILEMASTER_LOG_POS填写第二个主节点查询出来的bin文件信息

# 先关闭子同步
stop slave;
# 在配置从子同步
CHANGE MASTER TO MASTER_HOST='192.168.0.198',
MASTER_USER='myMaster2',
MASTER_PASSWORD='myMaster2',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=1129;
# 打开子同步
start slave;
# 查看状态
show slave status\G;

如果双主节点的状态都是下面yes那么就完成了

然后我们就在各自的数据库中操作下看看对方有没有发生变化

非法操作导致同步失败解决办法

使用主从模式,永远都要是主写,子读,如果子进行写的话,那么就会报错,然后同步就会卡主了,一直报错

遇到同步失败的情况解决办法:
将主和从数据结构保持一致(可以使用navicat进行数据结构同步)
关闭子同步stop slave;
重置子同步 reset slave;
查询主信息

重新配置子

然后查询子状态

点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复如有侵权,请私信联系我感谢,配合,希望我的努力对你有帮助^_^

相关文章