MySQL数据库之主从复制与读写分离

172 阅读21分钟

主从复制 ★★★

一、MySQL主从复制的相关程序

  • 日志

    • 二进制日志
    • 中继日志(relay log)
  • 线程

    • 主服务器 mysqldump线程 (传输二进制日志给从)
    • 从服务器 ①io线程(接收主的二进制日志,写入中继日志);
    • 从服务器 ②sql线程(读取中继日志,写入数据库)

二、 MySQL主从复制的原理 ★★★

01216fe7fa4969129dc264d8151d4e1.jpg

1.主节点负责用户的写操作,用户发起写操作后,会修改数据库

2.数据库修改后,会更新主节点上的二进制日志

3.从服务器会开启io线程,主动请求和主服务器同步

4.主服务器会产生一个dump线程,一边读取二进制日志,一边将二进制日志通过网络传给从服务器

5.从服务器会将二进制日志写入中继日志,这时只是生成了一个文件,并没有同步

6.从服务器再开启,sql线程将中继日志中的操作写入数据库完成更新

三、MySQL支持的复制类型

  • STATEMENT

    基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。

  • ROW

基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。

  • MIXED

混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

注意:复制需要考虑二进制日志事件记录格式

四、主从复制

1. 主从复制

fe172c136ea4423a93c1c32a7d561d5.jpg

  • 主服务器:192.168.100.40
  • 从服务器:192.168.100.50

主服务器节点

  1. 启用二进制日志,为当前节点设置一个全局惟一的ID号
[root@localhost ~]#  systemctl stop firewalld
[root@localhost ~]#  setenforce 0

[root@localhost ~]#  vim /etc/my.cnf
server-id=40                   //指明数据库的编号,区分自己的日志和别人的日志
log-bin=/data/mysql/mysql-bin  //指明二进制日志所存在的目录

[root@localhost ~]#  mkdir -p /data/mysql         //建立文件夹
[root@localhost ~]#  chown -R mysql.mysql /data/  //修改权限
[root@localhost ~]#  systemctl restart mysqld     //重启服务

image.png

image.png

  1. 创建有复制权限的用户账号
[root@localhost ~]#  mysql -uroot -pabc123
mysql> grant replication slave on *.* to test@'192.168.100.%' identified by 'Admin@123';
//注意:先建立用户,再看日志位置。否则建立用户这步操作不会记录在日志中

image.png

  1. 查看二进制日志的文件和位置开始进行复制
mysql> show master status;
//查看同步文件和同步的位置

image.png

从服务器节点

  1. 开启二进制日志
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0

[root@localhost ~]# vim /etc/my.cnf
server-id=50   //要和主不一样,否则会造成主从复制失败
log-bin=/data/mysql/mysql-bin

[root@localhost ~]# mkdir -p /data/mysql
[root@localhost ~]# chown -R mysql.mysql /data/
[root@localhost ~]# systemctl restart mysqld

image.png

image.png

  1. 使用有复制权限的用户账号连接至主服务器,并启动复制线程
[root@localhost ~]#  mysql -uroot -pabc123
mysql> help change master to   //使用帮助,复制参数进行修改

CHANGE MASTER TO
  MASTER_HOST='192.168.100.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=449;
//最后两行要与主节点中show master status;显示的数据相对应

mysql> start slave;          //开启io线程和sql线程,开启主从复制
mysql> show slave status\G;  //查看从服务器状态
mysql> show processlist;     //查看进程列表

image.png

image.png

image.png

image.png

验证:在主服务器上新建库,看从服务器是否同步

create database db1;
//在主节点上建立数据测试


注意:
如果两个线程不是Yes
stop slave;
reset slave  all; //清空主从配置
重新配置

image.png

image.png

2. 完备+主从复制

fe172c136ea4423a93c1c32a7d561d5.jpg

  • 主服务器:192.168.100.40
  • 从服务器:192.168.100.50

假设主节点的数据库已经运行了一段时间,产生了一定量的数据,主从复制只能复制开启后数据,那之前的数据如何处理?

主服务器节点

启用二进制日志
[root@localhost ~]#  systemctl stop firewalld
[root@localhost ~]#  setenforce 0
[root@localhost ~]#  vim /etc/my.cnf
server-id=50                  
log-bin=/data/mysql/mysql-bin  
[root@localhost ~]#  mkdir -p /data/mysql         //建立文件夹
[root@localhost ~]#  chown -R mysql.mysql /data/  //修改权限
[root@localhost ~]#  systemctl restart mysqld     //重启服务

导入数据库
[root@localhost ~]#  mysql  -uroot -pabc123  <  /opt/hellodb_innodb.sql  
[root@localhost ~]#  mysql  -uroot -pabc123 -e "select * from hellodb.students"  //查看是否有数据

完备
[root@localhost ~]#  mysqldump -uroot -pabc123 -A -F --master-data=1 --single-transaction > /data/all.sql

创建用户
[root@localhost ~]#  mysql  -uroot -pabc123
mysql> create   user  test@'192.168.100.%' identified by "Admin@123"; //新建主从复制用户
mysql> grant replication slave on *.*  to test@'192.168.100.%';       //授权主从复制用户

拷贝备份文件
[root@localhost ~]#  scp /data/all.sql  192.168.100.50:/opt

image.png

image.png

image.png

从服务器节点

启用二进制日志
[root@localhost ~]#  systemctl stop firewalld
[root@localhost ~]#  setenforce 0
[root@localhost ~]#  vim /etc/my.cnf
server-id=70
log-bin=/data/mysql/mysql-bin
[root@localhost ~]# mkdir -p /data/mysql
[root@localhost ~]# chown -R mysql.mysql /data/
[root@localhost ~]# systemctl restart mysqld

修改备份脚本
[root@localhost ~]# vim  /opt/all.sql
//找到 CHANGE MASTER TO 的行修改如下
CHANGE MASTER TO
  MASTER_HOST='192.168.100.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=154;
//由于之前再备份的时候加入了 --master-data=1 选项,就添加了主从复制的选项000002文件的154位置往后开始主从复制
//000002文件154位置之前的配置由备份文件自行实现 

导入数据库
[root@localhost ~]# mysql -uroot -pabc123
mysql> set sql_log_bin=0;    //临时关闭二进制日志
mysql> source /opt/all.sql   //导入数据库
mysql> start  slave;         //开启主从复制
mysql> show slave status\G;  //查看从节点的状态

image.png

image.png

image.png

image.png

image.png

3. 复制错误解决方法

从节点一般是只读模式,如果从节点里写入了数据那么主从复制就会失败,有可能主键冲突等等。

解决方法

  • 忽略错误, 跳过错误,手动修复,适用于主从之间数据差不大
  • 重建从服务器 ,适用于数据差比较大
//系统变量,指定跳过复制事件的个数
SET GLOBAL sql_slave_skip_counter = N

//服务器选项,只读系统变量,指定跳过事件的ID
[mysqld]
slave_skip_errors=1007|ALL  

示例:复制冲突的解决

//先在从上建表
create table info (id int,name char(10),age char(10));

//再在主上建表  插入信息
create table info (id int,name char(10),age char(10));
insert info values(1,'a',10);

//此时报错 从主机会报错
show  slave  status\G

//方法1:可以跳过错误
stop slave;
set global sql_slave_skip_counter=1;
start slave;

//方法2
vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
slave_skip_errors=1007|ALL 
systemctl restart mysqld

4. 级联 主从复制

需要在中间的从服务器启用log_slave_updates配置 ,实现中间slave节点能将master的二进制日志在本机进行数据库更新,并且也同时更新本机的二进制,从而实现级联复制。

7f62168b0e9e000b0e9bf7c3cdc51e1.jpg

  • 7-1 主服务器节点 192.168.100.40
  • 7-2 二级服务器节点 192.168.100.50
  • 7-3 从服务器节点 192.168.100.60

主服务器节点:192.168.100.40

[root@localhost ~]#  systemctl stop firewalld
[root@localhost ~]#  setenforce 0

[root@localhost ~]#  vim /etc/my.cnf
server-id=40                   //指明数据库的编号,区分自己的日志和别人的日志
log-bin=/data/mysql/mysql-bin  //指明二进制日志所存在的目录

[root@localhost ~]#  mkdir -p /data/mysql         //建立文件夹
[root@localhost ~]#  chown -R mysql.mysql /data/  //修改权限
[root@localhost ~]#  systemctl restart mysqld     //重启服务
[root@localhost ~]#  mysql -uroot -pabc123
mysql> grant replication slave on *.* to test@'192.168.100.%' identified by 'Admin@123';
//注意:先建立用户,再看日志位置。否则建立用户这步操作不会记录在日志中
mysql> show master status;
//查看同步文件和同步的位置

image.png

image.png

二级服务器节点:192.168.100.50

//启用二进制日志
[root@localhost ~]#  systemctl stop firewalld
[root@localhost ~]#  setenforce 0
[root@localhost ~]#  vim /etc/my.cnf
server-id=50
log-bin=/data/mysql/mysql-bin
log_slave_updates           //级联操作必须加的,只在级联节点上操作
[root@localhost ~]#  mkdir -p /data/mysql
[root@localhost ~]#  chown -R mysql.mysql /data/
[root@localhost ~]#  systemctl restart mysqld

[root@localhost ~]#  mysql -uroot -pabc123
CHANGE MASTER TO
  MASTER_HOST='192.168.100.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=449;

mysql> grant replication slave on *.* to test@'192.168.100.%' identified by 'Admin@123';    //检查以下有没有test用户,没有的话建立一个用户
mysql> start slave;         //开启线程,开启主从复制
mysql> show slave status\G; //查看状态
mysql> show master logs;    //查看从节点的复制位置

image.png

image.png

image.png

image.png

从服务器节点:192.168.100.60

//启用二进制日志
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# vim /etc/my.cnf
server-id=70
log-bin=/data/mysql/mysql-bin
[root@localhost ~]# mkdir -p /data/mysql
[root@localhost ~]# chown -R mysql.mysql /data/
[root@localhost ~]# systemctl restart mysqld

[root@localhost ~]# mysql -uroot -pabc123
CHANGE MASTER TO
  MASTER_HOST='192.168.100.50',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=449;

mysql> start slave;         //开启线程,开启主从复制
mysql> show slave status\G; //查看状态

image.png

image.png

image.png

验证:在主服务器上新建库,看二级服务器和从服务器是否同步

create database db1;
//在主节点上建立数据测试
show databases;
//查看数据库信息

image.png

image.png

image.png

5. 半同步复制

  • 异步复制:主服务器只管发,不管从服务器是否同步成功
  • 同步复制:主服务器需要等待所有从服务器完成同步
  • 半同步复制:主服务器只要有一台从服务器同步成功即可

dd88000431f83f3792773a20ab94a68.jpg

  • 7-1 主服务器 192.168.100.40
  • 7-2 从服务器1 192.168.100.50
  • 7-3 从服务器2 192.168.100.60

主服务器:192.168.100.40

[root@localhost ~]#  systemctl stop firewalld
[root@localhost ~]#  setenforce 0
[root@localhost ~]#  vim /etc/my.cnf
server_id=40
log-bin=/data/mysql-bin
[root@localhost ~]#  mkdir /data
[root@localhost ~]#  chown -R mysql.mysql /data/
[root@localhost ~]#  systemctl restart mysqld

[root@localhost ~]#  mysql -uroot -pabc123
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';  //安装插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled=1;      //开启半同步(临时修改变量)
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 3000; //设置3s内无法同步,也将返回成功信息给客户端
mysql> grant replication slave on *.* to test@'192.168.100.%' identified by 'Admin@123';  //建立复制用户
mysql> show  master  status;

mysql> SHOW GLOBAL VARIABLES LIKE '%semi%'; //查看半同步状态
mysql> show global status like '%semi%';    //查看半同步客户端

image.png

image.png

image.png

从服务器1:192.168.100.50

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]#  vim /etc/my.cnf
server_id=50
[root@localhost ~]#  systemctl restart mysqld

[root@localhost ~]#  mysql -uroot -pabc123
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1;

CHANGE MASTER TO
  MASTER_HOST='192.168.100.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=912;

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

image.png

image.png

image.png

从服务器2:192.168.100.60

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# vim /etc/my.cnf
server_id=60
[root@localhost ~]# systemctl restart mysqld

[root@localhost ~]#  mysql -uroot -pabc123
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1;

CHANGE MASTER TO
  MASTER_HOST='192.168.100.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=912;

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

image.png

image.png

image.png

五、主从复制的问题与解决方案

1. 造成主从不一致的原因

  • 主库binlog格式为 Statement ,同步到从库执行后可能造成主从不一致。
  • 主库执行更改前有执行set sql_log_bin=0,会使主库不记录binlog,从库也无法变更这部分数据。
  • 从节点未设置只读,误操作写入数据
  • 主库或从库意外宕机,宕机可能会造成binlog或者relaylog文件出现损坏,导致主从不一致
  • 主从实例版本不一致,特别是高版本是主,低版本为从的情况下,主数据库上面支持的功能,从数
  • 据库上面可能不支持该功能
  • MySQL自身bug导致

2. 据库主从数据不一致的解决方案

方法一:忽略错误后,继续同步

该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况。

方式二:重新做主从,完全同步

该方法适用于主从库数据相差较大,或者要求数据完全统一的情况。

3. mysql从服务器挂了 恢复后怎么保证数据同步?

  • 物理方法::rsync 磁盘文件同步。 使用文件恢复,主节点需要停服务。
  • 主从复制::将从节点原有库删除,通过偏移量,重新做一次主从复制。

4. 特别注意

  • 如何确定从服务器落后于主服务器
mysql> show slave status\G;
............................
 Seconds_Behind_Master: 0    //落后主服务器多少
............................
  • 如何确定主从节点数据是否一致
percona-toolkit   需要借助工具
  • 数据库不一致如何修复
删除从数据库,重新复制

读写分离

一、MySQL读写分离的概念

1. 什么是读写分离?

读写分离,基本的原理是让主数据库处理事务性增、改、删操作( INSERT、UPDATE、DELETE) 而从数据库处理SELECT查询(读)操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。

2. 为什么要读写分离呢?

  • 因为数据库的“写”(写10000条数据可能要3分钟)操作是比较耗时的。
  • 但是数据库的“读”(读10000条数据可能只要5秒钟)。
  • 所以读写分离,解决的是,数据库的写入 :影响了查询的效率

3. 什么时候要读写分离?

数据库不一定要读写分离,如果程序使用数据库较多时而更新少查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。

二、MySQL读写分离的方式有哪些

1. 基于程序代码内部实现

在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。 优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。 但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大。

2. 基于中间代理层实现

代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。

  • MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。由于使用MySQL Proxy 需要写大量的Lua脚本,这些Lua并不是现成的,而是需要自己去写。这对于并不熟悉MySQL Proxy 内置变量和MySQL Protocol 的人来说是非常困难的。
  • Atlas。是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。
  • Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层。
  • Mycat。是一款流行的基于Java语言编写的数据库中间件,是一个实现了MySql协议的服务器,其核心功能是分库分表。配合数据库的主从模式还可以实现读写分离。

三、MySQL 中间件代理服务器

数据库主要分为两大类:关系型数据库NoSQL 数据库

  • 关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据。主流的 MySQL、Oracle、MS SQL Server 和 DB2 都属于这类传统数据库。
  • NoSQL 数据库,全称为 Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。主要分为临时性键值存储(Redis、memcached)、永久性键值存储(ROMA、Redis)、面向文档的数据库(MongoDB、CouchDB)、面向列的数据库(Cassandra、HBase),每种 NoSQL 都有其特有的使用场景及优点。

Oracle,mysql 等传统的关系数据库非常成熟并且已大规模商用,为什么还要用 NoSQL 数据库呢? 主要是由于随着互联网发展,数据量越来越大,对性能要求越来越高,传统数据库存在着先天性的缺陷,即单机(单库)性能瓶颈,并且扩展困难。这样既有单机单库瓶颈,却又扩展困难,自然无法满足日益增长的海量数据存储及其性能要求,所以才会出现了各种不同的 NoSQL 产品,NoSQL 根本性的优势在于在云计算时代,简单、易于大规模分布式扩展,并且读写性能非常高

关系型数据库NoSQL 数据库
特点①数据关系模型基于关系模型,结构化存储,完整性约束②基于二维表及其之间的联系,需要连接、并、交、差、除等数据操作③采用结构化的查询语言(SQL)做数据读写④操作需要数据的一致性,需要事务甚至是强一致性①非结构化的存储②基于多维关系模型③具有特有的使用场景
优点①保持数据的一致性(事务处理)②可以进行 join 等复杂查询③通用化,技术成熟①高并发,大数据下读写能力较强②基本支持分布式,易于扩展,可伸缩③简单,弱结构化存储
缺点①数据读写必须经过 sql 解析,大量数据、高并发下读写性能不足②对数据做读写,或修改数据结构时需要加锁,影响并发操作③无法适应非结构化存储④扩展困难⑤昂贵、复杂①join 等复杂操作能力较弱②事务支持较弱③通用性差④无完整约束复杂业务场景支持较差

四、Mycat

1. Mycat的介绍

  • 一个彻底开源的,面向企业应用开发的大数据库集群
  • 支持事务、ACID、可以替代MySQL的加强版数据库
  • 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
  • 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
  • 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
  • 一个新颖的数据库中间件产品

2. Mycat的应用场景

Mycat适用的场景很丰富,以下是几个典型的应用场景:

  • 单纯的读写分离,此时配置最为简单,支持读写分离,主从切换
  • 分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片
  • 多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化报表系统,借助于Mycat的分表能力,处理大规模报表的统计
  • 替代Hbase,分析大数据,作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择

3. 通过Mycat实现读写分离

  • Mycat(不安装mysql):192.168.100.30
  • master 主服务器:192.168.100.40
  • slave 从服务器:192.168.100.50
  • 客户端:192.168.100.60

mycat服务器(192.168.100.30)

注意:mycat服务器上不能装mysql

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]#  cd /data         //上传mycat二进制包
[root@localhost data]# rz -E
rz waiting to receive.
[root@localhost data]# ls
Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz
[root@localhost data]#  mkdir /apps   //创建/apps文件夹
[root@localhost data]#  tar xf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /apps/   //解压mycat包至/apps下
[root@localhost data]#  cd /apps
[root@localhost apps]#  echo 'PATH=/apps/mycat/bin:$PATH' > /etc/profile.d/mycat.sh  //设置变量环境
[root@localhost apps]#  . /etc/profile.d/mycat.sh
[root@localhost apps]#  mycat start   //启动mycat
[root@localhost apps]#  mycat status  //查看状态
[root@localhost apps]#  tail -f /apps/mycat/logs/wrapper.log  //查看日志文件,启动成功日志末尾会出现successfully

image.png

master主服务器配置(192.168.100.40)

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]#  vim /etc/my.cnf
  server_id=40
  log-bin=/data/mysql/mysql-bin
[root@localhost ~]#  mkdir -p /data/mysql
[root@localhost ~]#  chown -R mysql.mysql /data/
[root@localhost ~]#  systemctl restart mysqld

[root@localhost ~]#  mysql -uroot -pabc123
mysql> grant replication slave on *.* to test@'192.168.100.%' identified by 'Admin@123';
mysql> show master status;


image.png

image.png

slave从服务器配置(192.168.100.50)

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]#  vim /etc/my.cnf
  server_id=50
  log-bin=/data/mysql/mysql-bin
[root@localhost ~]#  mkdir -p /data/mysql
[root@localhost ~]#  chown -R mysql.mysql /data/
[root@localhost ~]#  systemctl restart mysqld

[root@localhost ~]#  mysql -uroot -pabc123
CHANGE MASTER TO
  MASTER_HOST='192.168.100.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=449;
  
mysql> start slave;
mysql> show slave status\G;

image.png

image.png

image.png

完成主从复制后

[root@localhost ~]# cd /opt
[root@localhost opt]# rz -E
rz waiting to receive.
[root@localhost opt]# ls
hellodb_innodb.sql  rh
[root@localhost opt]# mysql -uroot -pabc123 < /opt/hellodb_innodb.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
//主从配置完成后,在master服务器上上传库文件,并在从服务器上验证主从同步

image.png

image.png

客户端(102.168.100.60)

测试连接Mycat数据库

[root@localhost ~]#  mysql -uroot -p123456 -h192.168.100.30 -P8066

image.png

Mycat服务器(192.168.100.30)

修改Mycat配置文件:/apps/mycat/conf/server.xml

[root@localhost apps]#  cd mycat/
[root@localhost mycat]#  ls
bin  catlet  conf  lib  logs  tmlogs  version.txt
[root@localhost mycat]#  cd conf/
[root@localhost conf]#  cp server.xml server.xml.bak  //先备份!!!
[root@localhost conf]#  vim server.xml
<property name="serverPort">3306</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="dataNodeIdleCheckPeriod">300000</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property>
//去掉44行行注释,以及对应的行末注释
//修改45行端口号为3306
//删除46行行末注释:5 * 60 * 1000L; //连接空>    闲检查

[root@localhost conf]#  mycat restart  //重新加载mycat
[root@localhost conf]#  mycat status   //查看状态

image.png

image.png

image.png

修改Mycat配置文件:/apps/mycat/conf/schema.xml

schema.xml是最主要的配置项,此文件关联mysql读写分离策略,读写分离、分库分表策略、分片节点都是在此文件中配置的.MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的。

[root@localhost conf]# ls
autopartition-long.txt      ehcache.xml                  partition-range-mod.txt               sequence_http_conf.properties  zkconf
auto-sharding-long.txt      index_to_charset.properties  rule.xml                              sequence_time_conf.properties  zkdownload
auto-sharding-rang-mod.txt  log4j2.xml                   schema.xml                            server.xml
cacheservice.properties     migrateTables.properties     sequence_conf.properties              server.xml.bak
dbseq.sql                   myid.properties              sequence_db_conf.properties           sharding-by-enum.txt
dbseq - utf8mb4.sql         partition-hash-int.txt       sequence_distributed_conf.properties  wrapper.conf

[root@localhost conf]#  cp schema.xml schema.xml.bak
[root@localhost conf]#  vim schema.xml   //删除所有内容,重新写入以下内容

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema>
        <dataNode name="dn1" dataHost="localhost1" database="hellodb" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="host1" url="192.168.100.40:3306" user="root" password="Admin@123">
                 <readHost host="host2" url="192.168.100.50:3306" user="root" password="Admin@123"/>
                </writeHost>
        </dataHost>
</mycat:schema>

[root@localhost conf]#  mycat restart
[root@localhost conf]#  mycat status

image.png

image.png

image.png

在master主服务器上授权,并在slave从服务器查看是否同步

在主服务器上授权
[root@localhost ~]#  mysql -uroot -pabc123
mysql> GRANT ALL ON *.* TO 'root'@'192.168.100.%' IDENTIFIED BY 'Admin@123';

[root@localhost ~]#  mysql -uroot -pabc123
mysql> select user,host from mysql.user;

image.png

客户机连接Mycat并测试读写分离

//主从服务器上都打开通用日志
mysql> set global general_log=1;

//在主从服务器上实时查看通用日志
主服务器
[root@localhost mysql]#  tail -f /var/lib/mysql/localhost.log
从服务器
[root@localhost mysql]#  tail -f /var/lib/mysql/localhost.log

//客户机连接mycat
[root@localhost ~]#  mysql -uroot -p123456 -h 192.168.100.30

在客户机上select查表,并查看主从服务器实时日志,可以看到只有`从服务器`上有日志变化显示
mysql> select * from students;

在客户机上插入数据,并查看主从服务器实时日志,可以看到只有`主服务器`上有日志变化显示,成功实现读写分离
mysql> insert students values(null,'xue',25,'M',1,3);

主服务器上都打开通用日志

image.png

从服务器上实时查看通用日志

image.png

客户机端连接Mycat

在客户机上select查表,并查看主从服务器实时日志,可以看到只有从服务器上有日志变化显示

image.png

image.png

在客户机上插入数据,并查看主从服务器实时日志,可以看到只有主服务器上有日志变化显示,成功实现读写分离

image.png

image.png