mysql主从复制架构

2022-08-18  本文已影响0人  sunpy

为什么要设计mysql主从复制架构


为了解决mysql中出现单点故障的问题,进而设计了mysql主从架构,保障整体服务性能和稳定。mysql提供的复制也是一种高性能高可用方案,实现最终一致性。而且主从架构的设计,往往是一主库,一从库,主从库之间异步同步数据。可以让主服务器写,让从服务器读,这样可以实现读写分离。

主从复制原理


  1. master将数据更改记录到二进制日志binlog。
  2. slave将主服务器的二进制日志复制到自己的中继日志relay log。
  3. 服务器重做中继日志中的日志,把更改应用到自己的数据库,达到数据最终一致性。

docker-compose搭建主从复制架构


镜像名称 内外端口 容器名称
mysql:8.0.29 3389:3306 mysql-master
mysql:8.0.29 3379:3306 mysql-slave
  1. 编写docker-compose文件:
version: "3"
services:
   mysql-master:
     image: mysql:8.0.29
     ports:
       - 3389:3306
     volumes:
       - /home/mysql/master-slave/master/conf/:/etc/mysql/conf.d 
       - /home/mysql/master-slave/master/data/:/var/lib/mysql
       - /home/mysql/master-slave/master/log/:/var/log/mysql
     environment:
       MYSQL_ROOT_PASSWORD: spy1679358426
       MYSQL_DATABASE: sunpy-mysql
       MYSQL_USER: sunpy
       MYSQL_PASSWORD: spy1679358426
     restart: always
     container_name: mysql-master
   mysql-slave:
     image: mysql:8.0.29
     ports:
       - 3379:3306
     volumes:
       - /home/mysql/master-slave/slave/conf/:/etc/mysql/conf.d 
       - /home/mysql/master-slave/slave/data/:/var/lib/mysql
       - /home/mysql/master-slave/slave/log/:/var/log/mysql
     environment:
       MYSQL_ROOT_PASSWORD: spy1679358426
       MYSQL_DATABASE: sunpy-mysql
       MYSQL_USER: sunpy
       MYSQL_PASSWORD: spy1679358426
     restart: always
     container_name: mysql-slave
  1. 启动mysql编排容器:
docker-compose -f mysql.yml up -d
  1. 配置my.cnf文件:
    这部分在我们的外部conf目录下配置就行了,因为我们挂载了外部文件夹。

主:

[mysqld]

server-id=1
log-bin=mysql-bin
binlog_format=MIXED
max_binlog_size = 124M
expire_logs_days = 3
binlog_ignore_db = mysql,performance_schema,information_schema,sys

从:

[mysqld]

server_id = 2
log_bin = mysql-bin
binlog_format=MIXED
max_binlog_size = 124M
expire_logs_days = 3
replicate-ignore-db=mysql,performance_schema,information_schema,sys
relay_log_recovery = 1
log_slave_updates = 1
  1. 查看主从状态:
mysql> show master status;
+------------------+----------+--------------+-------------------------------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                                | Executed_Gtid_Set |
+------------------+----------+--------------+-------------------------------------------------+-------------------+
| mysql-bin.000068 |      157 |              | mysql,performance_schema,information_schema,sys |                   |
+------------------+----------+--------------+-------------------------------------------------+-------------------+
1 row in set (2.33 sec)
  1. change命令同步主从数据
change master to 
master_host='xxx.xx.xxx.xxx', 
master_user='root', 
master_password='xxxxx', 
master_port=3389, 
master_log_file='mysql-bin.000068',
master_log_pos= 0, 
master_connect_retry=30;
  1. 开启从库
mysql> start slave;
Query OK, 0 rows affected (0.44 sec)

查看是否开启:

验证:
master库新增一条记录,slave库也会新增一条记录。

问题思考:主从复制延迟


思考:在测试的时候发现,主从复制并不是很快的,不会马上同步数据。
问题:如果我们采取读写分离方式,那么主库数据写了一条记录。如果我们写完后,再从库去刷新数据列表记录,会发现记录还未同步过来。这种实时性要求比较高的时候该怎么办?

问题思考:主从库数据不一致


思考:主库新增数据成功,然后主库数据通过binlog同步的时候,发现binlog无法同步,造成主从库结果不一致。
答:
GTID方案,就是主库生成一个GTID标识,同当前记录一同写入到binlog中。从库将binlog日志写入到relay-log中。从relay-log中获取GTID,通过GTID获取从库中的binlog,如果有记录,说明GTID事务已执行。没有记录,那么从库会从 relay-log 中执行该 GTID 的事务,并记录到 binlog 中。

mysql开启GTID:


[mysqld]
# 启用GTID
gtid-mode=on        
# 强制GTID的一致性                
enforce-gtid-consistency=true       
# slave更新是否记入日志(1表示记入、0表示不记入)
log-slave-updates=1                 

参考:
https://blog.csdn.net/JohnnyG2000/article/details/124701214

https://time.geekbang.org/column/article/145095?screen=full

上一篇下一篇

猜你喜欢

热点阅读