mysql主从复制架构实现(代码片段)

郭怀远 郭怀远     2023-03-16     471

关键词:

文章目录


一、MySQL集群概述

1.集群的主要类型

  • 高可用集群
  • 高可用集群是指通过特殊软件把独立的服务器连接起来,组成一个能够**提供故障切换功能的集群

2. 如何衡量高可用

可用性级别(指标)年度宕机时间描述叫法
99%3.65天/年基本可用系统2个9
99.9%8.76小时/年可用系统3个9
99.99%52.6分钟/年高可用系统4个9
99.999%5.3分钟/年抗故障系统5个9
99.9999%32秒/年容错系统6个9

计算方法:

1年 = 365天 = 8760小时
99% = 8760 * 1% = 8760 * 0.01 = 87.6小时=3.65天
99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小时
99.99 = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟
99.999 = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟

3. 常用的集群架构

  • MySQL Replication
  • MySQL Cluster
  • MySQL Group Replication (MGR) 5.7.17 多主一从
  • MariaDB Galera Cluster
  • MHA|Keepalived|HeartBeat|Lvs,Haproxy等技术构建高可用集群

二、MySQL复制介绍

1.什么是MySQL复制

  • Replication可以实现将数据从一台数据库服务器(master)复制到一台到多台数据库服务器(slave)
  • 默认情况下,属于异步复制,所以无需维持长连接

2.MySQL复制原理

简单来说,master将数据库的改变写入二进制日志,slave同步这些二进制日志,并根据这些二进制日志进行数据重演操作,实现数据异步同步。


详细描述:

当主从同步配置完毕后:

  1. slave端的IO线程发送请求给master端的binlog dump线程
  2. master端binlog dump线程获取二进制日志信息(文件名和位置信息)发送给slave端的IO线程
  3. salve端IO线程获取到的内容依次写到slave端relay log(中继日志)里,并把master端的bin-log文件名和位置记录到master.info里
  4. salve端的SQL线程,检测到relay log中内容更新,就会解析relay log里更新的内容,并执行这些操作,从而达到和master数据一致
  • relay log中继日志
    作用:记录从(slave)服务器接收来自主(master)服务器的二进制日志.

场景:用于主从复制

master主服务器将自己的二进制日志发送给slave从服务器,slave先保存在自己的中继日志中,然后再执行自己本地的relay log里的sql达到数据库更改和master保持一致。

如何开启?
默认中继日志没有开启,可以通过修改配置文件完成开启,如下

# vim my.cnf
[mysqld]
#指定二进制日志存放位置及文件名
relay-log=/mysql_3306/data/relaylog

3. MySQL复制架构

1) 双机热备(AB复制)


默认情况下,master接受读写请求,slave只接受读请求以减轻master的压力。

2) 级联复制


**优点:**进一步分担读压力

**缺点:**slave1 出现故障,后面的所有级联slave服务器都会同步失败

3) 并联复制(一主多从)


优点:解决上面的slave1的单点故障,同时也分担读压力

缺点:间接增加master的压力(传输二进制日志压力)

4)双主复制

特点:

从命名来看,两台master好像都能接受读、写请求,但实际上,往往运作的过程中,同一时刻只有其中一台master会接受写请求,另外一台接受读请求。

三、MySQL主从复制的搭建(AB复制)

1. 传统AB复制架构(M-S)

注意:在配置MySQL主从架构时,必须保证数据库的版本高度一致,这里同一统一版本为5.7.31

2. 环境准备

两个Linux服务器

编号主机名称主机ip角色信息
1master192.168.44.120master服务器
2slave192.168.44.150slave从服务器

由于两台机器处于集群架构,需要互相连接。绑定主机名称与IP地址到/etc/hosts

# vim /etc/hosts


192.168.44.120 master
192.168.44.150 slave

3. MySQL主从复制核心思路

  1. slave必须安装相同版本的mysql数据库软件
  2. master端必须开启二进制日志;slave端必须开启relay log日志
  3. master端和slave端的server-id号不能一致
  4. slave端配置向master来同步数据
    • master端必须创建一个复制用户
    • 保证master和slave端初始数据一致
    • 配置主从复制(slave端)

4. MySQL主从复制实现

上传MySQL软件包到Master与Slave服务器

在Master端安装、初始化以及运行mysql软件
安装需求:

选项值(自定义也可以采用默认形式)
安装路径/usr/local/mysql
数据路径/usr/local/mysql/data
端口号3306

1) 安装MySQL软件

vim mysql.sh
#!/bin/bash
yum install libaio -y
tar -xf mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz
rm -rf /usr/local/mysql
mv mysql-5.7.31-linux-glibc2.12-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
rm -rf /etc/my.cnf
cd /usr/local/mysql
mkdir mysql-files
chown mysql:mysql mysql-files
chmod 750 mysql-files
bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql &> /root/password.txt
bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data
cp support-files/mysql.server /etc/init.d/mysqld
service mysqld start
echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
source /etc/profile

# source mysql.sh

Shell脚本其实就是命令的堆砌,把一堆Linux命令写在同一个文件中,一起执行。

2)安全配置

# mysql_secure_installation
先输入刚刚默认生成的密码(保存在/root/psssword.txt里)
再设置新密码
确认新密码
再直接回车
后面一路y

3) 配置my.cnf(重点开启二进制日志)

# cd /usr/local/mysql
# vim my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/master.err
log-bin=/usr/local/mysql/data/binlog		=>	  一定要开启二进制日志
server-id=10
character_set_server=utf8mb4			 	=>    utf8mb4相当于utf8升级版

配置完成后,重启mysqld服务
# service mysqld restart
# chkconfig --add mysqld
# chkconfig mysqld on

在Slave从服务器端安装mysql软件(不需要初始化)

① 安装MySQL软件

# vim mysql.sh
#!/bin/bash
yum install libaio -y
tar -xf mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz
rm -rf /usr/local/mysql
mv mysql-5.7.31-linux-glibc2.12-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
rm -rf /etc/my.cnf
cd /usr/local/mysql
mkdir mysql-files
chown mysql:mysql mysql-files
chmod 750 mysql-files
cp support-files/mysql.server /etc/init.d/mysqld
echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
source /etc/profile

执行脚本文件

# source mysql.sh

相对于主服务器MySQL的安装与配置,从服务器端不需要进行初始化操作,因为其数据将来都来自于主服务器。

② 配置my.cnf文件

# cd /usr/local/mysql
# vim my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3310
log-error=/usr/local/mysql/data/slave.err
relay-log=/usr/local/mysql/data/relaylog			=>    	开启中继日志
server-id=100
character_set_server=utf8mb4

③ 把master主服务器的数据目录同步到slave从服务器

—把master服务器中的mysqld停止掉

# service mysqld stop
  1. 把master服务器中的/usr/local/mysql/data目录下的auto.cnf文件删除
# rm -rf /usr/local/mysql/data/auto.cnf

3.把master服务器中/usr/local/mysql中的data目录拷贝一份到slave从服务器的/usr/local/mysql目录

# rsync -av /usr/local/mysql/data root@10.1.1.100:/usr/local/mysql/
  1. 同步完成后,把主服务器与从服务器中的mysqld启动
service mysqld start

④ 配置master-slave主从同步
1.在master主服务器中创建一个账号,专门用于实现数据同步
MySQL5.7及以下版本:

mysql> grant replication slave on *.* to 'slave'@'192.168.44.%' identified by '123';

MySQL新版本中:

mysql> create user 'slave'@'10.1.1.%' identified by '123';
mysql> grant replication slave on *.* to 'slave'@'10.1.1.%';
mysql> flush privileges;

2.在master中锁表,然后查看二进制文件的名称及位置

mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000003 |      449 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+

3.在slave从服务器中,使用change master to指定主服务器,并实现数据同步

mysql> change master to master_host='192.1668.44.120',master_user='slave',master_password='123',master_port=3306,master_log_file='binlog.000003',master_log_pos=449;

master_host:主机的IP地址
master_user:主机的user账号
master_password:主机的user账号密码
master_port:主机MySQL的端口号
master_log_file:二进制日志文件名称(从上一步操作获取)
master_log_pos:二进制日志文件位置 (从上一步操作获取)
技巧:主从复制的change master to语句记不住怎么办?答:求帮助,mysql> help change master to;
CHANGE MASTER TO
MASTER_HOST='master2.example.com',
MASTER_USER='replication',
MASTER_PASSWORD='password',
MASTER_PORT=3306,
MASTER_LOG_FILE='master2-bin.001',
MASTER_LOG_POS=4,
MASTER_CONNECT_RETRY=10;

4.启动slave数据同步

mysql> start slave;
mysql> show slave status\\G


常见问题解决方案

在配置主从时,一般遇到错误,大部分都是change master to语句写错了(80%),解决方案:

mysql> stop slave;
mysql> reset slave;
mysql>change master to master_host='192.1668.44.120',master_user='slave',master_password='123',master_port=3306,master_log_file='binlog.000003',master_log_pos=449;

mysql> start slave;

⑤ 主MASTER服务器解锁

mysql> unlock tables;
Query OK, 0 rows affected (0.01 sec)

5.总结

  1. 主从复制必须保证两台数据库实例的server-id不一致
  2. 主服务器必须开启二进制日志;从服务器必须开启中继日志
  3. 主从复制搭建必须保证初始数据一致
  4. 主服务器必须要给从服务器创建一个复制用户,并授予复制权限
  5. Master—>Slave架构,主写会同步到从;而从写不会同步到主

6. slave从服务器不小心写入数据解决方案

先在主服务器master上创建测试数据

mysql> create database db_test;
mysql> use db_test;
mysql> create table tb_student (
    -> id int auto_increment primary key,
    -> name varchar(20),
    -> sex enum('男','女')
    -> ) default charset=utf8mb4;

mysql> insert into tb_student values (null,'张三','男');
mysql> insert into tb_student values (null,'李四','男');

在从服务器slave上查看数据是否同步

mysql> use db_test;
mysql> select * from tb_student;
+----+--------+------+
| id | name   | sex  |
+----+--------+------+
|  1 | 张三   | 男   |
|  2 | 李四   | 男   |
+----+--------+------+

这时我们在从服务器slave上插入一条数据

mysql> insert into tb_student values(null,'老王','男');


mysql> insert into tb_student values(null,'老六','女');

再往主服务master服务器上插入这两条数据

mysql> insert into tb_student values(null,'老王','男');
mysql> insert into tb_student values(null,'老六','女');

再在从服务器上查看状态

mysql> show slave status\\G


遇到以上问题:如果数量较少,还可以通过跳过当前语句的方式解决。但是如果从服务器写入数据过多,则以上架构必须要重新搭建了!

解决方案:

问:

如果由于人为操作或者其他原因直接将数据更改到从服务器导致数据同步失效,怎么解决?

答:可以通过变量sql_slave_skip_counter临时跳过事务进行处理

SET GLOBAL sql_slave_skip_counter = N  	N代表跳过N个事务
举例说明:
mysql> SET GLOBAL sql_slave_skip_counter=1;
mysql> stop slave;
mysql> start slave;
注意:
1. 跳过事务应该在slave上进行
2. 传统的AB复制方式可以使用变量:sql_slave_skip_counter,基于GTIDs的方式不支持

执行完以上操作后,就又可以同步了

四、基于GTIDs的AB复制架构(M-S)

1.GTIDs概述

  • 什么是GTIDs以及有什么特点?
  1. GTIDs(Global transaction identifiers)全局事务标识符,是mysql 5.6新加入的一项技术

  2. 当使用GTIDs时,每一个事务都可以被识别并且跟踪

  3. 添加新的slave或者当发生故障需要将master身份或者角色迁移到slave上时,都无需考虑是哪一个二进制日志以及哪个position值,极大简化了相关操作

  4. GTIDs是完全基于事务的,因此不支持MYISAM存储引擎

  5. GTID由source_id和transaction_id组成

    1)source_id来自于server_uuid,可以在auto.cnf中看到

    2)transation_id是一个序列数字,自动生成.

  • 使用GTIDs的限制条件有哪些?
  1. 不支持非事务引擎(MyISAM),因为可能会导致多个gtid分配给同一个事务
  2. create table … select 语句不支持(主库语法报错)
  3. create/drop temporary table 语句不支持
  4. 必须使用enforce-gtid-consistency参数
  5. sql-slave-skip-counter不支持(传统的跳过错误方式)
  6. GTID复制环境中必须要求统一开启和GTID或者关闭GTID
  7. 在mysql 5.6.7之前,使用mysql_upgrade命令会出现问题

2. 基于GTIDs的主从复制

接下来我们就利用已有的环境升级至基于GITDs的Replication

〇 思路

  1. 修改配置文件支持GTIDs (主+从)
  2. 重启数据库 (主+从)
  3. 为了保证数据一致性,master和slave设置为只读模式 (主+从)
  4. 从服务器上重新配置同步(从)

3. 基于GTIDs的主从复制实现

1)修改配置文件支持GTIDs

修改master服务器的my.cnf配置文件

# vim my.cnf
在末尾添加一下内容
gtid-mode=on
log-slave-updates=1
enforce-gtid-consistency

再修改slave服务器的my.cnf配置文件

# rm -rf /usr/local/mysql/data/binlog.*
# vim my.cnf
...
log-bin=/usr/local/mysql/data/binlog	=>   必须要开启二进制
gtid-mode=on
log-slave-updates=1
enforce-gtid-consistency
skip-slave-start	 =>    当MASTER主服务器GTIDs没有启动时,跳过SLAVE服务器的启动

说明:
1)开启GITDs需要在master和slave上都配置gtid-mode,log-bin,log-slave-updates,enforce-gtid-consistency(该参数在5.6.9之前是–disable-gtid-unsafe-statement)
2)其次,slave还需要增加skip-slave-start参数,目的是启动的时候,先不要把slave起来,需要做一些配置
3)基于GTIDs复制从服务器必须开启二进制日志!

2)重新启动mysqld服务

主从都要重新启动

# service mysqld restart

3)主从配置只读模式

mysql> set @@global.read_only=ON;

4) slave重新配置change master to

mysql> stop slave;
mysql> reset slave;
mysql> change master to master_host='192.168.44.120',master_user='slave',master_password='123',master_port=3306,master_auto_position=1;

注意:
1.确保有复制用户
2.主要区别于传统复制的参数是:master_auto_position=1

mysql> start slave;
mysql> show slave status\\G

5)关闭主从服务器的只读模式

set @@global.read_only=OFF;

在主服务器上插入数据

mysql> use db_test;
mysql> insert into tb_student values (null,'小明','男');

在从服务上传查询测试

mysql> use db_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from tb_student;
+----+--------+------+
| id | name   | sex  |
+----+--------+------+
|  1 | 张三   | 男   |
|  2 | 李四   | 男   |
|  3 | 老王   | 男   |
|  4 | 老六   | 女   |
|  5 | 赵六   | 女   |
|  6 | 小明   | 男   |
+----+--------+------+

4. slave从服务器不小心写入数据解决方案

方法一:跳过事务
先模拟写入数据,在从服务器上

mysql> insert into tb_student values (null,'八戒','男');

data目录下找 relay.*的文件查看

通过大概时间找到要跳过的事物

指定需要跳过的GTIDs编号
SET GTID_NEXT='aaa-bbb-ccc-ddd:N';
开始一个空事务
BEGIN;
COMMIT;
使用下一个自动生成的全局事务ID。
SET GTID_NEXT='AUTOMATIC';

举例说明:
mysql> stop slave;
mysql> SET @@SESSION.GTID_NEXT= 'bc4b2e0e-29a4-11ed-a811-000c29492e7c:2'/*!*/;
mysql> BEGIN;
mysql> commit;
mysql> SET @@SESSION.GTID_NEXT= 'AUTOMATIC';	
mysql> start slave;
mysql> show slave status\\G

说明:需要跳过哪个事务,需要手动查看relaylog文件得到
[root@slave1 data]# ../bin/mysqlbinlog relay.000003|less

方法二:重新同步data目录,重新change master to…
上面有写

mysql中间件proxysql实现mysql主从架构读写分离(代码片段)

实验主机Master:192.168.0.17Slave:192.168.0.20Proxysql:192.168.0.30建议关闭防火墙建立Master:192.168.0.17与Slave:192.168.0.20的MySQL主从复制架构Proxysql:192.168.0.30主机上基于yum安装proxysql[[email protected]~20:21:05]#cat< 查看详情

mysql主从复制的简单搭建(代码片段)

文章目录1、MySQL一主一从的简单搭建1.1、主从复制简介1.2、MySQL主从复制简介1.3、主从复制的架构1.4、前期准备1.5、主要配置实现1.5.1、测试环境1.5.2、配置my.cnf文件1.5.3、启动mysql测试1.5.4、配置主从结构1.5.4.1、主服务器配置1.5.4... 查看详情

mysql主从复制的简单搭建(代码片段)

文章目录1、MySQL一主一从的简单搭建1.1、主从复制简介1.2、MySQL主从复制简介1.3、主从复制的架构1.4、前期准备1.5、主要配置实现1.5.1、测试环境1.5.2、配置my.cnf文件1.5.3、启动mysql测试1.5.4、配置主从结构1.5.4.1、主服务器配置1.5.4... 查看详情

mysql主从复制与读写分离(原理深刻,过程详细,值得一看)(代码片段)

...是读写分离(2)为什么要读写分离(3)什么时候要读写分离(4)主从复制与读写分离2.MySQL主从复制(1)mysql支持的复制类型(2)主从复制的工作过程(3)mysql主从复制高延迟的原因(4)mysql主从复制高延迟的解决办法3.常见的MySQL读写分离方式(1)... 查看详情

mysql主从复制详解(代码片段)

前言:在MySQL中,主从架构应该是最基础、最常用的一种架构了。后续的读写分离、多活高可用架构等大多都依赖于主从复制。主从复制也是我们学习MySQL过程中必不可少的一部分,关于主从复制的文章有很多,笔者也来凑凑热... 查看详情

linux学习-mysql主从复制(代码片段)

...:辅助实现备份高可用异地灾备Scaleout:分摊负载主从架构中,不使用MySQL代理,如何实现主的写,从的读??双主模型:无法减轻MySQL写操作读写分离:mysql-proxyamoebacobarMySQL5.6:GTID,Multi-threadReplication... 查看详情

mysql主从同步与读写分离(代码片段)

MySQL主从同步MySQLAB复制1.对指定库的异地同步。2.MySQL主-->从复制架构的实现。3.MySQL服务器的只读控制。主从:单向复制时,建议将从库设置为只读。主从复制的原理:Master,记录数据更改操作。-启动binlog日志-设置binlog日志格... 查看详情

mysql主从同步与读写分离(代码片段)

MySQL主从同步MySQLAB复制1.对指定库的异地同步。2.MySQL主-->从复制架构的实现。3.MySQL服务器的只读控制。主从:单向复制时,建议将从库设置为只读。主从复制的原理:Master,记录数据更改操作。-启动binlog日志-设置binlog日志格... 查看详情

mysql主从同步与读写分离(代码片段)

MySQL主从同步MySQLAB复制1.对指定库的异地同步。2.MySQL主-->从复制架构的实现。3.MySQL服务器的只读控制。主从:单向复制时,建议将从库设置为只读。主从复制的原理:Master,记录数据更改操作。-启动binlog日志-设置binlog日志格... 查看详情

mysql深入浅出主从复制数据同步原理(代码片段)

【MySQL】深入浅出主从复制数据同步原理参考资料:全解MySQL之主从篇:死磕主从复制中数据同步原理与优化MySQL日志:undolog、redolog、binlog有什么用?文章目录【MySQL】深入浅出主从复制数据同步原理一、主从复制... 查看详情

mysql学习-mysql8.0配置双主复制+keepalived实现高可用架构(代码片段)

一般小型公司数据库,使用主从复制即可保证数据库的高可用,但是一旦主数据库故障,切换到从库需要一定的时间,这样就导致了停机时间过长,不能及时恢复业务。使用双主(master)配合keepalived这种mysql高可用架构也是基于... 查看详情

《mysql系列-主从相关》docker安装mysql,实现主从复制(代码片段)

Docker安装MySQL,实现主从复制一、前言1Docker安装MySQL参考历史文章Docker安装MySQL,准备两台MySQL容器master节点容器名称MySQL01容器IDfaf2312fd62a端口33061slave节点容器名称MySQL01容器IDdfc693c2bb04端口330622MySQL主从复制配置实操参考... 查看详情

电商平台lnmp架构之mysql优化(代码片段)

电商平台lnmp架构之mysql优化1.Mysql的主从复制2.mysql一主两从3.基于GTID(全局事务标识)的主从复制4.半同步复制5.mysql异步复制6.延迟复制(SQL线程延迟)7.并行复制8.mysql的全同步复制(组复制)9.读写分离10.MHA高可用1.Mysql的主从... 查看详情

mysql5.7使用gtid模式搭建主从复制架构(代码片段)

一、架构两台mysql服务器做一主一从,172.28.18.69(主)172.28.18.78(从)二、分别编译安装mysql5.71、下载mysql5.7.26源码包[[email protected]1/]#mkdir/usr/local/src/mysql-5.7.26-src[[email protected]-1]#cd/usr/local/src/mysql-5.7 查看详情

mysql数据库运维之主从复制搭建(代码片段)

...机多实例搭建,本篇文章将在上篇文章的基础上介绍MySQL主从复制过程,其中常见的复制架构有:异步复制,半同步复制及同步复制。常用的复制架构有异步复制及半同步复制!一、常见的复制架构1、主主复制(1)结构图:(2... 查看详情

mysql数据库运维之主从复制搭建(代码片段)

...机多实例搭建,本篇文章将在上篇文章的基础上介绍MySQL主从复制过程,其中常见的复制架构有:异步复制,半同步复制及同步复制。常用的复制架构有异步复制及半同步复制!一、常见的复制架构1、主主复制(1)结构图:(2... 查看详情

如何实现mysql的读写分离?mysql主从复制原理的是啥?如何解决mysql主从同步的延时问题?(代码片段)

...?如何实现MySQL的读写分离?  其实很简单,就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后主库会自动把数据给同 查看详情

从理论到实战,彻底搞懂mysql主从复制原理(代码片段)

文章目录前言常见主从架构模式单向主从双向主从级联主从多主一从主从原理基于语句复制(STATEMENT)基于行复制(ROW)混合模式(MIXED)主从实战一主一从双向主从级联主从多主一从半同步复制实战GTID前... 查看详情