当前位置: 首页 > news >正文

50.Mysql主从复制与读写分离

Mysql主从复制与读写分离

主从复制的作用

1.实时灾备,用于故障切换

2.读写分离,提供查询服务

3.数据备份,避免影响业务

主从形式

一主一从,主主复制,一主多从,(扩展系统读取性能),多主一从(MySQL 5.7+支持),级联复制

主从复制原理

主从复制步骤:

  1. 主库将所有写操作记录到binlog日志,并通过log dump线程传送给从库的I/O线程
  2. 从库生成I/O线程和SQL线程
  3. I/O线程请求主库的binlog,并将日志写入relay log(中继日志)文件
  4. SQL线程读取relay log文件中的日志,解析成具体操作,实现主从数据一致

关闭防火墙和selinux

确保主从数据一致

先在主库新建一个数据库,然后新建一个表

mysql> create database xyh;
Query OK, 1 row affected (0.00 sec)mysql> use xyh;
Database changed
mysql> create table student(id int primary key,-> name varchar(10), -> age int);
mysql> insert into student values (1,"zhangsan",23),-> (2,"lisi",21),-> (3,"wangwu",20),-> (4,"zhaoliu",22),-> (5,"xiaohao",24);
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0mysql> select * from student;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   23 |
|  2 | lisi     |   21 |
|  3 | wangwu   |   20 |
|  4 | zhaoliu  |   22 |
|  5 | xiaohao  |   24 |
+----+----------+------+
5 rows in set (0.00 sec)

在备份主库时需要给主库上锁,避免在备份期间有其他人在写入导致数据不一致,在备份完成后才能退出,因此需要另开一个终端来备份

mysql> FLUSH TABLES WITH READ LOCK;

备份主库

[root@xieyuhui2 ~]# mysqldump -uroot -predhat --all-databases > /opt/all-20250921.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

将主库文件传输给从库

[root@xieyuhui2 ~]# scp /opt/all-20250921.sql root@192.168.100.10:/opt/

将文件导入从库确保数据一致

[root@xieyuhui ~]# mysql -uroot -predhat < /opt/all-20250921.sql
mysql> select * from xyh.student;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   23 |
|  2 | lisi     |   21 |
|  3 | wangwu   |   20 |
|  4 | zhaoliu  |   22 |
|  5 | xiaohao  |   24 |
+----+----------+------+
5 rows in set (0.00 sec)

创建主从同步账号

在主库里创建同步账号授权给从数据库使用

mysql> create user 'root'@'192.168.100.10' identified by 'redhat';
Query OK, 0 rows affected (0.00 sec)mysql> grant replication slave on *.* to 'root'@'192.168.100.10';
Query OK, 0 rows affected (0.01 sec) #授权mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

配置主数据库

[root@xieyuhui2 ~]# vim /etc/my.cnf[mysqld]
basedir = /usr/local/mysql
datadir = /opt/data
socket = /tmp/mysql.sock
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve
log-bin=mysql-bin   #启用binlog日志
server-id=1		#数据库服务器的唯一标识,从库的id值必须比主库大
symbolic-links=0
log-error=/var/log/mysqld.log

重启mysql服务

[root@xieyuhui2 ~]# systemctl restart mysqld

查看主库状态

[root@xieyuhui2 ~]# mysql -uroot -predhat -e 'show master status';
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

配置从数据库

[root@xieyuhui ~]# vim /etc/my.cnf[mysqld]
basedir = /usr/local/mysql
datadir = /opt/data
socket = /tmp/mysql.sock
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve
server-id=2	
relay-log=mysql-relay-bin	#启用中继日志
symbolic-links=0
log-error=/var/log/mysqld.log

重启从库mysql服务

[root@xieyuhui ~]# systemctl restart mysqld

配置并启动主从复制

mysql> change master to-> master_host='192.168.100.20',-> master_user='root',-> master_password='redhat',-> master_log_file='mysql-bin.000001',-> master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.01 sec)mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

查看从库状态

mysql> show slave status \G
*************************** 1. row ***************************Slave_IO_State: Connecting to masterMaster_Host: 192.168.100.20Master_User: rootMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 154Relay_Log_File: mysql-relay-bin.000001Relay_Log_Pos: 4Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: Yes   #必须为yesSlave_SQL_Running: Yes	 #必须为yesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 154Relay_Log_Space: 154Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 2003Last_IO_Error: error connecting to master 'root@192.168.100.20:3306' - retry-time: 60  retries: 1Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 0Master_UUID: Master_Info_File: /opt/data/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for more updatesMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: 250921 22:13:00Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 
1 row in set (0.00 sec)

测试验证

在主服务器的xyh库的student表中插入数据

mysql> select * from student;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   23 |
|  2 | lisi     |   21 |
|  3 | wangwu   |   20 |
|  4 | zhaoliu  |   22 |
|  5 | xiaohao  |   24 |
+----+----------+------+
5 rows in set (0.00 sec)mysql> insert into student values(6,"haoshuai",19);
Query OK, 1 row affected (0.02 sec)mysql> select * from student;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   23 |
|  2 | lisi     |   21 |
|  3 | wangwu   |   20 |
|  4 | zhaoliu  |   22 |
|  5 | xiaohao  |   24 |
|  6 | haoshuai |   19 |
+----+----------+------+
6 rows in set (0.00 sec)

在从库查看

mysql> select * from student;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   23 |
|  2 | lisi     |   21 |
|  3 | wangwu   |   20 |
|  4 | zhaoliu  |   22 |
|  5 | xiaohao  |   24 |
|  6 | haoshuai |   19 |
+----+----------+------+
6 rows in set (0.00 sec)

读写分离

什么是读写分离?

读写分离是一种数据库架构模式,基本原理是:

主数据库(Master)处理所有写操作(INSERT、UPDATE、DELETE)

从数据库(Slave)处理SELECT查询操作

通过数据库复制将写操作的变更同步到从数据库

为什么要读写分离?

写操作相对耗时,可能影响查询性能

分离读写操作可提升数据库并发负载能力

优化数据库性能,提高系统响应速度

适用场景

应用程序读多写少的情况

需要提升数据库查询性能的场景

数据库负载较高,需要分担压力的情况

基于中间代理层实现

常见中间件:

  1. MySQL-Proxy:MySQL开源项目,使用Lua脚本进行SQL判断
  2. Atlas:奇虎360基于MySQL-Proxy优化开发
  3. Amoeba:Java开发,阿里巴巴用于生产环境(不支持事务和存储过程)
  4. Mycat:Java编写的数据库中间件,支持分库分表和读写分离

本次使用mycat作为中间代理

前置条件

关闭防火墙和SELinux

配置时间同步

主从数据库已完成主从复制配置

配置/etc/hosts文件:

192.168.100.10 xieyuhui.example.com slave
192.168.100.20 xieyuhui2.example.com master
192.168.100.30 xieyuhui3.example.com mycat

发送给其他主机

[root@xieyuhui2 ~]# scp /etc/hosts root@192.168.100.10:/etc/hosts[root@xieyuhui2 ~]# scp /etc/hosts root@192.168.100.30:/etc/hosts

在mycat节点安装java环境

[root@xieyuhui3 ~]# yum  -y  install  java java-devel

部署mycat服务,将Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz上传到mycat的/root目录下,并解压到/usr/local
cd /root

[root@xieyuhui3 ~]# tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/

定义环境变量

[root@xieyuhui3 ~]# echo export MYCAT_HOME=/usr/local/mycat/ >> /etc/profile
[root@xieyuhui3 ~]# source /etc/profile

编辑mycat服务读写分离的schema.xml,设置数据库写入节点为master,读取节点slave,注意IP要修改

清除全部内容,并且写入新内容
[root@xieyuhui3 ~]# vim /usr/local/mycat/conf/schema.xml<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="USERDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1"></schema> 
<dataNode name="dn1" dataHost="localhost1" database="xyh" />  
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" dbType="mysql" dbDriver="native" writeType="0" switchType="1"  slaveThreshold="100">      <heartbeat>select user()</heartbeat><writeHost host="hostM1" url="192.168.100.20:3306" user="root" password="redhat">        <readHost host="hostS1" url="192.168.100.10:3306" user="root" password="redhat" />    </writeHost></dataHost></mycat:schema>

编辑mycat用户的/usr/local/mycat/conf/目录下的server.xml,修改root用户的密码redhat,访问mycat的逻辑库为USERDB

[root@xieyuhui3 ~]# vim /usr/local/mycat/conf/server.xml
在文件末尾处删除如下<user name="root"><property name="password">user</property><property name="schemas">TESTDB</property><property name="readOnly">true</property></user><user name="root"><property name="password">redhat</property><property name="schemas">USERDB</property>

启动mycat服务

[root@xieyuhui3 ~]# cd /usr/local/mycat/bin
[root@xieyuhui3 bin]# ./mycat start

查看8066,9066端口是否开启

[root@xieyuhui3 bin]# ss -anlt
State       Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN      0      128            *:111                        *:*                  
LISTEN      0      128            *:6000                       *:*                  
LISTEN      0      5      192.168.122.1:53                         *:*                  
LISTEN      0      128            *:22                         *:*                  
LISTEN      0      128    127.0.0.1:631                        *:*                  
LISTEN      0      100    127.0.0.1:25                         *:*                  
LISTEN      0      128    127.0.0.1:6010                       *:*                  
LISTEN      0      1      127.0.0.1:32000                      *:*                  
LISTEN      0      100           :::9066                      :::*                  
LISTEN      0      50            :::44749                     :::*                  
LISTEN      0      128           :::111                       :::*                  
LISTEN      0      128           :::6000                      :::*                  
LISTEN      0      128           :::22                        :::*                  
LISTEN      0      128          ::1:631                       :::*                  
LISTEN      0      50            :::36697                     :::*                  
LISTEN      0      100          ::1:25                        :::*                  
LISTEN      0      128          ::1:6010                      :::*                  
LISTEN      0      50            :::1984                      :::*                  
LISTEN      0      100           :::8066                      :::*  

8066为数据端口,9066为数据端口,用于管理mycat集群状态

在master和slave节点分别给root数据库用户授权,因为默认情况下,数据库用户root不允许远程登录

mysql> grant all privileges on *.* to 'root'@'%' identified by 'redhat' with grant option;
Query OK, 0 rows affected, 1 warning (0.01 sec)

在mycat节点安装[root@xieyuhui3 ~]# yum install mariadb mariadb-server让其能够使用mysql命令

[root@xieyuhui3 ~]# yum install mariadb mariadb-server  -y

在本地使用数据端口登录到mysql数据中,查询和插入数据,然后使用管理端口查看读写分离效果

[root@xieyuhui3 ~]# mysql -uroot -predhat -P8066 -h127.0.0.1
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server (OpenCloundDB)Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]>MySQL [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| USERDB   |
+----------+
1 row in set (0.00 sec)MySQL [USERDB]> show tables;
+---------------+
| Tables_in_xyh |
+---------------+
| student       |
+---------------+
1 row in set (0.00 sec)MySQL [USERDB]> select * from student;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   23 |
|  2 | lisi     |   21 |
|  3 | wangwu   |   20 |
|  4 | zhaoliu  |   22 |
|  5 | xiaohao  |   24 |
|  6 | haoshuai |   19 |
+----+----------+------+
6 rows in set (0.03 sec)插入数据
MySQL [USERDB]> insert into student values(7,"guoqiang",55);
Query OK, 1 row affected (0.00 sec)MySQL [USERDB]> select * from student;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   23 |
|  2 | lisi     |   21 |
|  3 | wangwu   |   20 |
|  4 | zhaoliu  |   22 |
|  5 | xiaohao  |   24 |
|  6 | haoshuai |   19 |
|  7 | guoqiang |   55 |
+----+----------+------+
7 rows in set (0.00 sec)

通过管理接口9066来查看读写分离的情况,看写入的次数和查看的次数

[root@xieyuhui3 ~]# mysql -uroot -predhat -P9066 -h127.0.0.1MySQL [(none)]> show @@datasource;

在这里插入图片描述

主库写了1次,从库读了5次

http://www.dtcms.com/a/394091.html

相关文章:

  • 软件设计师,经典计算题
  • Python的bz2库讲解
  • 抖音2025创作者大会:优质内容播放时长增220%,推出四大计划
  • C++面向对象编程之继承:深入理解与应用实践
  • [Windows] OFD转PDF 1.2.0
  • TDengine 聚合函数 VAR_POP 用户手册
  • 跨域及其解决方法
  • LeetCode:37.二叉树的最大深度
  • 【C++深学日志】C++“类”的完全指南--从基础到实践(一)
  • BUS-消息总线
  • 23种设计模式之【单例模式模式】-核心原理与 Java实践
  • 精度至上,杜绝失真,机器视觉检测中为何常用BMP格式?
  • 关于wireshark流量分析软件brim(Zui)安装方法
  • springboot3.4.1集成pulsar
  • 信息量、熵、KL散度和交叉熵
  • 使用Python一站式提取Word、Excel、PDF 和PPT文档内容v1.0
  • 线性代数 | REF / RREF
  • TLCP的一些内容
  • dock容器网络存储相关练习
  • 鸿蒙Next ArkTS卡片提供方开发指南:从入门到实战
  • Netty LengthFieldBasedFrameDecoder
  • 后端_HTTP 接口签名防篡改实战指南
  • 区块链论文速读 CCF A--WWW 2025(5)
  • 机器学习周报十四
  • 如何解决stun服务无法打洞建立p2p连接的问题
  • 解决项目实践中 java.lang.NoSuchMethodError:的问题
  • JavaSE-多线程(5.2)- ReentrantLock (源码解析,公平模式)
  • 2025华为杯A题B题C题D题E题F题选题建议思路数学建模研研究生数学建模思路代码文章成品
  • 【记录】Docker|Docker中git克隆私有库的安全方法
  • Web之防XSS(跨站脚本攻击)