MySQL主从复制的原理及其读写分离配置

  • Post author:
  • Post category:mysql



目录


一、MySQL主从复制介绍


1、MySQL支持的复制类型


2、为什么要做主从复制


3、主从复制原理


4、MySQL主从复制数据同步的策略


二、MySQL主从复制的配置(一主双从)


1、主库配置


2、从库配置


三、利用MyCAT2配置读写分离


1、创建数据源


2、创建集群


3、创建逻辑库


4、修改逻辑库的数据源


5、重启MyCAT,配置完成


一、MySQL主从复制介绍

MySQL主从复制是MySQL内建的复制功能,是构建大型、高性能应用程序的基础。

简单来说,主从复制是将数据库主机(master)中的数据或产生数据的SQL语句复制到另一个或多个数据库主机(slaves)上,之后再执行一遍即可得到主机(master)的数据。

在这个复制过程中,master主机被称为主服务器,slave主机被称为从服务器。

1、MySQL支持的复制类型

  • 基于语句(statement)的复制:在主服务器上执行SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率较高。
  • 基于行(row)的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍。从MySQL 5.0开始支持。
  • 混合型(mixed)的复制:默认采用基于语句的复制,一旦发现基于语句的无法精确复制时,就会采用基于行的复制。

2、为什么要做主从复制

  • 灾备
  • 数据分布
  • 负载均衡
  • 读写分离
  • 提高并发能力
  • 提高可用性

3、主从复制原理

主要基于MySQL二进制日志

主要包括三个线程(2个I/O线程,1个SQL线程)

简言之,分三步曲进行:

  1. 主数据库有个 bin log 二进制文件,记录了所有增删改 SQL 语句。(IO线程)
  2. 从数据库把主数据库的 bin log 文件的 SQL 语句复制到自己的中继日志 relay log(IO线程)
  3. 从数据库的 relay log 重做日志文件,再执行一次这些sql语句。(SQL线程)

详细步骤:

  1. 从库通过手工执行change master to 语句连接主库,提供了连接的用户一切条件(user 、password、port、ip),并且让从库知道,二进制日志的起点位置(file名 position 号); start slave
  2. 从库的IO线程和主库的IO线程建立连接。
  3. 从库根据change master to 语句提供的file名和position号,IO线程向主库发起binlog的请求。
  4. 主库IO线程根据从库的请求,将本地binlog以events的方式发给从库IO线程。
  5. 从库IO线程接收binlog events,并存放到本地relay-log中,传送过来的信息,会记录到master.info中
  6. 从库SQL线程应用relay-log,并且把应用过的记录到relay-log.info中,默认情况下,已经应用过的relay 会自动被清理(purge)

4、MySQL主从复制数据同步的策略

以上就是主从复制的过程,当然,主从复制的过程有不同的策略方式进行数据的同步,主要包含以下几种:


  1. 同步策略

    :Master会等待所有的Slave都回应后才会提交,这个主从的同步的性能会严重的影响。

  2. 半同步策略

    :Master至少会等待一个Slave回应后提交。

  3. 异步策略

    :Master不用等待Slave回应就可以提交。

  4. 延迟策略

    :Slave要落后于Master指定的时间。

对于不同的业务需求,有不同的策略方案,但是一般都会采用最终一致性,不会要求强一致性,毕竟强一致性会严重影响性能。

二、MySQL主从复制的配置(一主双从)


大致步骤:

1.主库上(master):

在配置文件中选择唯一的server-id,开启binlog日志;

创建一个具有复制权限的用户

2.从库上(slave):

在配置文件中选择唯一的server-id,开启中继日志(默认开启);

连接至主库,并开启复制;

检查连接启动是否正常


环境准备:

MySQL版本:mysql 5.7.36

服务器:

IP地址 端口
主库 192.168.5.132 3306
从库1 192.168.5.133 3306
从库2 192.168.5.134 3306

1、主库配置


1)设置唯一server-id,开启binlog日志

修改配置文件;

[mysqld]
log_bin = mysql-bin
server_id = 132

重启mysql服务。


2)创建具有复制权限的用户账号

mysql> grant replication slave on *.* to 'rep'@'192.168.95.%' identified by
'123456';


3)锁表设置只读

为后面备份准备,注意生产环境要提前申请停机时间;

mysql> flush tables with read lock;


4)查看主库状态

查看主库状态,即当前日志文件名和二进制日志偏移量

mysql> show master status;


5)备份数据库数据

mysqldump -uroot -p -A -B |gzip > /backup/mysql_bak.$(date +%F).sql.gz


6)解锁

mysql> unlock tables;


7)主库备份数据上传到两个从库

scp /backup/mysql_bak.2023-04-03.sql.gz 192.168.5.133:~
scp /backup/mysql_bak.2023-04-03.sql.gz 192.168.5.134:~

2、从库配置


1)设置server-id值

#从库1
[mysqld]
server_id = 133
#从库2
[mysqld]
server_id = 134

重启数据库;


2)还原从主库拷贝过来的备份数据

zcat mysql_bak.2023-04-03.sql.gz | mysql -uroot -p

检查还原:

mysql -uroot -p -e ‘show databases;’


3)设定从主库同步

# 从库1
mysql> change master to
MASTER_HOST='192.168.5.133',
MASTER_PORT=3306,
MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=149;
# 从库2
mysql> change master to
MASTER_HOST='192.168.5.134',
MASTER_PORT=3306,
MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=149;


4)启动从库同步开关

mysql> start slave;


5)检查状态

mysql> show slave status\G

一定要注意Slave_IO_Running参数和Slave_SQL_Running参数应都为Yes,否则代表主从复制异常。这两个参数分别代表:

  • Slave_IO_Running:IO线程是否打开 YES/No/NULL
  • Slave_SQL_Running:SQL线程是否打开 YES/No/NULL

三、利用MyCAT2配置读写分离


大致步骤:

  1. 创建数据源
  2. 创建集群
  3. 创建逻辑库
  4. 修改逻辑库的数据源
  5. 测试读写分离是否成功


环境准备:

MyCAT版本:MyCAT2-1.21

新增一个MyCAT服务器

IP地址 端口
MyCAT服务器 192.168.5.136 8066

登录mycat客户端进行以下配置。

1、创建数据源

# 添加读写的数据源
/*+ mycat:createDataSource{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
"instanceType":"READ_WRITE",
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
"name":"m1",
"password":"123456",
"type":"JDBC",
"url":"jdbc:mysql://192.168.5.132:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8",
"user":"root",
"weight":0
} */;
# 添加读的数据源(从库1)
/*+ mycat:createDataSource{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
"instanceType":"READ",
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
"name":"m1s1",
"password":"123456",
"type":"JDBC",
"url":"jdbc:mysql://192.168.5.133:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8",
"user":"root",
"weight":0
} */;
# 添加读的数据源(从库2)
/*+ mycat:createDataSource{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
"instanceType":"READ",
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
"name":"m1s2",
"password":"123456",
"type":"JDBC",
"url":"jdbc:mysql://192.168.5.134:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8",
"user":"root",
"weight":0
} */;

查看数据源

/*+ mycat:showDataSources{} */;

这里由于篇幅原因,就给大家看一下数据源目录显示结果:

2、创建集群

/*! mycat:createCluster{
"clusterType":"MASTER_SLAVE",
"heartbeat":{
"heartbeatTimeout":1000,
"maxRetry":3,
"minSwitchTimeInterval":300,
"slaveThreshold":0
},
"masters":[
"m1"
],
"maxCon":2000,
"name":"prototype",
"readBalanceType":"BALANCE_ALL",
"replicas":[
"m1s1",
"m1s2"
],
"switchType":"SWITCH"
} */;

查询集群

/*+ mycat:showClusters{} */;

集群目录结果:

3、创建逻辑库

CREATE DATABASE db1 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

4、修改逻辑库的数据源

修改conf/schemas/db1.schema.json,在里面添加 “targetName”:”prototype”

vim /mycat-data/mycat/conf/schemas/db1.schema.json
cat /mycat-data/mycat/conf/schemas/db1.schema.json
{
	"customTables":{},
	"globalTables":{},
	"normalProcedures":{},
	"normalTables":{},
	"schemaName":"db1",
	"shardingTables":{},
	"views":{},
	"targetName":"prototype"
}

5、重启MyCAT,配置完成

cd /mycat-data/mycat/bin/
./mycat restart



版权声明:本文为m0_60861848原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。