1. mycat

本文详细介绍了数据库中间件mycat的使用,包括数据分片、分布式查询、主从复制与读写分离等核心功能。mycat不仅实现了分库分表,还支持全局序列号生成和多种高可用策略,是数据库扩展和优化的有效工具。
摘要由CSDN通过智能技术生成

1 数据分片

  1. 当一个数据库实例写操作过于频繁,很难由一台主机支撑时,我们可以将存放在同一个数据库实例中的数据分散存放到多个数据库实例中,从而提升性能
  2. 数据分片方式
    1. 水平切分(分表):将大表按某个字段的某种规则分散到多个节点库中,每个节点中包含一部分数据
    2. 垂直切分(分库):一个数据库由很多表构成,每个表对应不同的业务,垂直切分是指按照业务将表进行分类并分不到不同的节点上
    3. 混合切分:水平切分+垂直切分
  3. 数据分片原则
    1. 能不切分尽量不要切分
    2. 如果要切分一定要选择合适的切分规则,提前规划好
    3. 数据切分尽量通过数据冗余(同一份数据放到不同库中)或表分组来降低跨库join的可能
    4. 由于数据库中间件对数据join实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表join。

2 分布式查询

分布式查询处理的任务就是把一个分布式数据库上的高层次查询,转换为在本地数据库上的操作,将要查询的数据定位到各节点,使得查询在各节点进行,最后通过网络通信的操作汇聚查询结果

3 关系型数据库和NoSQL

  1. 关系型数据库:建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据,现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示,主流的是oracle、db2、sql server、mysql
  2. NOSQL(Not Only SQL):对不同于传统的关系数据库的数据库管理系统的统称,允许部分资料使用SQL系统存储,而其他资料允许使用NOSQL系统存储,其数据存储可以不需要固定的表格模式以及元数据,也经常会避免使用SQL的JOIN操作,一般有水平可扩展性的特征

3 mycat简介

3.1 定义
  1. 对于DBA:mycat是MySQL,而Mycat后面连接的MySQL就好比MySQL的存储引擎,如InnoDB、MyISAM等。mycat本身并不存储数据,数据是在后端的MySQL上存储的,因此数据可靠性以及事务都是MySQL保证的
  2. 对于开发人员:mycat是一个近似等于MySQL的数据库服务器,你可以用连接MySQL的方式去连接mycat,除了端口不同(mycat为8066,mysql为3306),大多数情况下,可以通过你熟悉的OR Mapping框架来访问mycat,但建议对于大的分片表,尽量使用基础的SQL语句,因为这样能达到最佳性能
  3. 对于架构师:mycat是一个强大的数据库中间件,可以用于读写分离、分库分表、容灾备份、多租户应用开发、云平台基础设施等,让你的架构具备很强的适应性和灵活性,借助于即将发布的mycat智能优化模块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的表映射到不同的存储引擎上,而整个应用的代码一行也不用改变
3.2 原理
  1. mycat拦截了用户发送过来的SQL语句,首先对SQL语句进行一些特定的分析,例如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL路由到后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户
3.3 应用场景
  1. 其实公司很少使用mycat的分库分表功能,一般只用到其主从复制和读写分离功能
3.4 数据库中间件对比
对比项目 mycat mango cobar heisenberg altas amoeba
数据切片 支持 支持 支持 支持 支持 支持
读写分离 支持 支持 支持 支持 支持 支持
宕机自动切换 支持 不支持 支持 不支持 半支持,影响写 不支持
mysql协议 前后端支持 JDBC 前端支持 前后端支持 前后端支持 JDBC
支持的数据库 mysql,oracle,mongodb,postgresql mysql mysql mysql mysql mysql,mongodb
社区活跃度 活跃 停滞 中等 停滞
文档资料 极丰富 较齐全 较齐全 较少 中等 缺少
是否开源 开源 开源 开源 开源 开源 开源
是否支持事务 弱XA 支持 单库强一致,分布式弱事务 单库强一致,多库弱事务 单库强一致,分布弱事务 不支持

4 mycat测试环境搭建

  1. 四台虚拟机,操作系统:centos6.5,内存:1g,cpu核数:1,硬盘:100g
4.1 mysql5.7.29安装
  1. 安装wget

    yum install wget -y
    
  2. 更换yum源

    #以下命令通过访问https://developer.aliyun.com/mirror/,选择centos中可以查找到
    #备份
    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    #替换
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
    #1. 2020年11月30日,centos6各大开源镜像站已经停止维护了
    #2. 因此会报错http://mirrors.aliyun.com/centos/6/os/x86_64/repodata/repomd.xml: [Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 404 Not Found",直接通过浏览器访问这个文件,发现根本不存在,这个6实际上是读取的当前centos的大版本号,只好将该文件中使用$releasever变量的地方,都改成7,如果原来/etc/yum.repos.d/CentOS-Base.repo中有好多文件,可以先全部删除后重新配置,否则下面步骤中可能还会访问http://mirrors.aliyun.com/centos/6/os/x86_64/repodata/repomd.xml
    #3. 但删除后,在安装Openssl时,会报错,因为使用的软件和当前操作系统大版本不匹配,因此可以尝试使用其他网站的yum源
    #4. curl -o /etc/yum.repos.d/CentOS-Base.repo https://www.xmpan.com/Centos-6-Vault-Aliyun.repo 
    vi /etc/yum.repos.d/CentOS-Base.repo
    :0,$s/$releasever/7/gi
    #清理安装包
    yum clean all
    #生成缓存
    yum makecache
    
  3. 查看系统中是否自带了mysql

    yum list installed | grep mysql
    
  4. 删除系统自带的mysql及其依赖(防止冲突)

    yum -y remove mysql-libs.x86_64
    
  5. 下载包含mysql的yum源的rpm包

    wget dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
    
  6. 使用yum安装rpm包

    #rpm :只能安装已经下载到本地机器上的rpm包,无法解决软件包的依赖关系
    #yum:在线下载并安装rpm包,能更新系统,能自动处理包与包之间的依赖问题
    yum install mysql-community-release-el6-5.noarch.rpm -y
    
  7. 修改mysql-community.repo文件

    #将5.6的enabled=1改为enabled=0,5.7的改为enabled=1
    vi /etc/yum.repos.d/mysql-community.repo
    
  8. 使用yum安装mysql

    yum install mysql-community-server -y
    
  9. 启动mysql服务并设置开机启动

    #1. 启动之前需要生成临时密码,需要用到证书,可能证书过期,需要进行更新操作
    yum update -y
    #2. 启动mysql服务
    service mysqld start
    #3. 设置mysql开机启动
    chkconfig mysqld on
    
  10. 获取mysql的临时密码

    #2020-12-20T18:40:45.644971Z 1 [Note] A temporary password is generated for root@localhost: XPfho+KM<7y#
    #其中XPfho+KM<7y#就是临时密码
    grep "password" /var/log/mysqld.log
    
  11. 使用临时密码登录

    mysql -uroot -p
    #输入临时密码XPfho+KM<7y#
    
  12. 修改密码

    set global validate_password_policy=0;
    set global validate_password_length=1;
    ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
    
  13. 修改远程访问权限

    grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
    flush privileges;
    
  14. 设置字符集为utf-8

    vi /etc/my.cnf
    #在[mysqld]下一行添加
    character-set-server=utf8
    #在文件末尾新增[client]段,并在[client]段下一行添加
    default-character-set=utf8
    #重启mysql
    service mysqld restart
    #查看字符集是否生效,两个参数内容中基本都是utf8就说明配置成功
    mysql -uroot -p123456
    show variables like 'char%';
    show variables like 'collation%';
    
4.2 mysql卸载
  1. 查看mysql相关的rpm包

    rpm -qa | grep -i mysql
    
  2. 删除所有rpm包

    rpm -ev mysql-community-libs-5.7.27-1.el6.x86_64 --nodeps
    
  3. 查找和mysql相关的文件

    find / -name mysql
    
  4. 删除全部文件

    rm -rf /var/lib/mysql
    rm -rf /var/lib/mysql/mysql
    rm -rf /etc/logrotate.d/mysql
    rm -rf /usr/share/mysql
    rm -rf /usr/bin/mysql
    rm -rf /usr/lib64/mysql
    
  5. 检查是否有内容未删除干净

    find / -name mysql
    rpm -qa | grep -i mysql
    
4.2 mycat安装
  1. 下载安装包:http://dl.mycat.org.cn/1.6.7.5/2020-4-10/

  2. 安装jdk

  3. 解压

    tar -zxvf Mycat-server-1.6.7.5-release-20200410174409-linux.tar.gz -C /usr/local
    
  4. 配置环境变量

    vi /etc/profile
    export MYCAT_HOME=/usr/local/mycat
    export PATH=$MYCAT_HOME/bin:$PATH:$JAVA_HOME/bin
    export PATH=$PATH:$MYCAT_HOME/bin
    source /etc/profile
    
  5. 修改/etc/hosts

    192.168.246.128 node01
    192.168.246.129 node02
    192.168.246.130 node03
    192.168.246.131 node04
    
4.3 mycat配置
  1. 进入/usr/local/mycat/conf目录

  2. 修改server.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mycat:server SYSTEM "server.dtd">
    <mycat:server xmlns:mycat="http://io.mycat/">
      <!--
      user标签:定义登录mycat的用户和权限
       property标签:设置具体的属性值
        password:密码,之后就可以通过mysql -uroot -p123456 -P 8066 -h 192.168.246.128登录mycat
        schemas:控制客户可访问的schema,如果有多个可用逗号分隔
       privileges标签:更精细的设置mycat用户对schema中的表的权限
    	system标签:设置字符集、线程数、全局序列类型等
     -->
      <user name="root" defaultAccount="true">
        <property name="password">123456</property>
        <!--2. 指定mycat中有哪些逻辑库-->
        <property name="schemas">TESTDB</property>
        <property name="defaultSchema">TESTDB</property>
      </user>
    </mycat:server>
    
  3. 修改schema.xml

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
      <!--
    		schema:定义mycat的逻辑库
          name:逻辑库名
          checkSQLschema:如果为true,那么当连接mycat的客户端执行语句select * from TESTDB.user;,mycat会自动将"TESTDB."去掉,防止发送到后端真正的mysql数据库中,由于mysql中没有TESTDB库而报错,但如果语句为select * from AAA.user;即语句中带的不是schema指定的名,那么不会将其去掉,因此该值建议设置为false
          sqlMaxLimit:连接mycat进行查询时,默认只返回前100条,即默认加一个limit 100,如果语句中本身使用了limit,那么此处配置失效
          randomDataNode:语句随机分配到一个分片节点
          dataNode:分片节点,用于绑定逻辑库到某个具体的database上
     -->
      <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
      </schema>
      <!--
      	dataNode:指定分片节点,分片节点:数据切分后,一个大表被分到不同的分片数据库中,每个表分片所在的数据库就是分片节点
    			name:分片节点名
    			dataHost:指定该分片节点所在节点主机名。节点主机:分片节点所在的机器
    			database:指定分片节点属于节点主机的哪个数据库,如果对应节点主机上没有这个数据库,使用mycat连接TESTDB时会超时,可以在mysql数据库上先执行create database msb;
    	-->
      <dataNode name="dn1" dataHost="host1" database="msb" />
      <!--
    		name:节点主机名
    		maxcon:指定每个读写实例连接池的最大连接
    		mincon:指定每个读写实例连接连接池的最小链接,初始化连接池的大小
    		balance:负载均衡类型,后面会具体讲解
    		writeType:写类型,后面会具体讲解
    		dbType:指定后端连接的数据库类型
    		dbDriver:连接后段数据库所使用的driver,可选择native和JDBC,如果连接的数据库是mysql或maridb,可以设置为native,如果为其他数据库,需要设置为JDBC
    		switchType:是否进行主从切换,后面会具体讲解
    	-->
      <dataHost name="host1" maxCon="1000" minCon="10" balance="0"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <!--指定检测mycat所连接的数据库实例是否宕机所用的语句-->
        <heartbeat>select user()</heartbeat>
        <writeHost host="hostM1" url="192.168.246.128:3306" user="root" password="123456">
          <readHost host="hostS1" url="192.168.246.128:3306" user="root" password="123456"></readHost>
        </writeHost>
      </dataHost>
    </mycat:schema>
    
  4. 启动mycat

    #1. 控制台启动,如果配置文件写错可以很方便看到报错信息
    mycat console
    #2. 后台启动
    mycat start
    #3. 查看状态
    mycat status
    
  5. 客户端连接mycat

    #-P:指定端口:9066为管理端口,8066为业务端口
    #-h:指定连接的mycat服务器地址
    mysql -uroot -p123456 -P 8066 -h 192.168.246.128
    
  6. 测试

    --发现只有一个TESTDB库,这是个逻辑库
    show databases;
    --使用这个逻辑库
    use TESTDB;
    --如果连接的为管理端口,显示不支持该语句
    --如果连接的为业务端口,那么可以看到该逻辑库对应的真实的数据库中(msb)中的表
    show tables;
    --查看可执行的命令
    show @@help;
    
4.4 mycat日志

/usr/local/mycat/logs/mycat.log

5 主从复制与读写分离

主机名 IP地址
node01 192.168.246.128
node02 192.168.246.129
node03 192.168.246.130
node04 192.168.246.131
5.1 一主一从
  1. node01和node02上各有一个mysql实例
  2. node01为主,node02为从
  3. 测试前最好将四个节点上都创建msb库,或都删除msb库,防止不统一造成的不一致
5.1.1 搭建
  1. node01:vi /etc/my.cnf

    #[mysqld]下配置
    #1. mysql服务唯一id,不同的mysql服务必须拥有全局唯一的id,不能为0,0表示拒绝任何连接
    server-id=1
    #2. 启动binlog
    log-bin=mysql-bin
    #3. 其实前两个配置完,就已经可以了
    #4. 设置不复制的数据库
    binlog-ignore-db=mysql
    binlog-ignore-db=information-schema
    #5. 设置复制的数据库
    binlog-do-db=msb
    #6. 设置binlog的格式:row、statement、mixed
    binlog_format=statement
    
  2. node02:vi /etc/my.cnf

    #[mysqld]下配置
    server-id=2
    #启动relay log
    relay-log=mysql-relay
    
  3. 重启node01和node02的mysql服务

    service mysqld restart
    
  4. node01:创建账户并授予replication slave权限

    --1. 建立用户
    CREATE USER 'root'@'%' IDENTIFIED BY '123456';
    --2. 授权
    grant replication slave on *.* to 'root'@'%' ;
    --3. 以上两句可以合并为1句
    grant replication slave on *.* to 'root'@'%' identified by '123456';
    --4. 建立用户时,如果提示密码太简单,可以修改密码安全级别
    set global validate_password_policy=0;
    set global validate_password_length=1;
    
  5. 获得master binlog复制点

    --node1上执行,会显示binlog日志名、复制点等信息
    show master status;
    
  6. node02:指定需要复制的主机

    --MASTER_LOG_POS:表示从日志中哪个位置开始读
    --MASTER_LOG_FILE:binlog日志名
    --这两个值来源于上面show master status;
    CHANGE MASTER TO MASTER_HOST='192.168.246.128',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=1640;
    
  7. node02:启动复制功能

    --node02上执行
    start slave;
    
  8. node02:查看从服务器状态

    --1. Slave_IO_Running和Slave_SQL_Running状态都为Yes就表示主从复制已正常开启
    --2. 如果有状态是No需要在日志/var/log/mysqld.log中查看报错信息
    --3. node02重置slave:stop slave;reset slave;
    --3. node01重置master:reset master;该动作会删除之前所有的binlog日志
    show slave status\G;
    
5.1.2 验证
  1. 创建数据库

    --注意建立主从复制关系之前,需要node01和node02上都没有msb这个数据库,假如node01上有,node02上没有,那么在node01上执行create时,node01会报错,因为无法重新创建数据库,而如果想先在node01上drop,node02会报错,因为node02上还没有数据库,而且由于在node02还原node01上的操作失败,会导致主从复制关系断开,即Slave_SQL_Running变为No,无法继续同步
    --1. 在node01上创建数据库
    create database msb;
    --2. 在node01上创建具体的表
    create table mytbl(id int,name varchar(20));
    --3. 在node01上插入数据
    insert into mytbl values(1,'zhangsan');
    --4. 在node02上验证发现数据已经同步成功,表示主从复制完成
    
  2. 插入语句

    1. 主插入语句,从能看到,但从插入语句主看不到
    2. 如果某表存在唯一索引,当从库插入后,主库再插入可以插入成功,但从库这边会由于违反唯一索引导致同步失败,此时Slave_SQL_Running变为No,后续同步也无法继续
    3. 因此从库是不能提供写入服务的
5.1.3 数据不一致解决方案
  1. 将从库数据全部清除
  2. 从库重新建立主从关系,注意MASTER_LOG_POS值为第一次建立主从关系时的值,而不是主上面的最新值
5.1.4 mycat配置读写分离
  1. node01执行

    --1. 下面语句会将主机名插入数据库中,当使用statement策略时,会按原来语句插入,因此node01执行该语句时,name列为node01,node02上还原该语句时,name列会插入node02
    insert into mytbl values(2,@@hostname);
    --2. 但此时我们如果通过mycat进行数据的访问,无论怎么查询数据,最终返回的name列值都是node01,说明每次读请求都发送到了node01这个主上,还未实现读写分离
    select * from mytbl;
    
  2. 修改schema.xml

    <!--
     banlance属性值解析
      1. 0:不开启读写分离,读写都发到writeHost
      2. 1:适用于双主双从模式,其中一个writeHost提供写的功能,剩下的writeHost和所有的readHost一起提供读的功能
      3. 2:读操作随机在writeHost和readHost上分发
      4. 3:在writeHost上写,readHost上读
    -->
    <dataHost name="host1" maxCon="1000" minCon="10" balance="2"
              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
      <heartbeat>select user()</heartbeat>
      <writeHost host="hostM1" url="192.168.246.128:3306" user="root" password="123456">
        <readHost host="hostS1" url="192.168.246.129:3306" user="root" password="123456"></readHost>
      </writeHost>
    </dataHost>
    
  3. 重启mycat

  4. 测试

    insert into mytbl values(3,@@hostname);
    --将balance配置为2后,发现name列的值随机出现node01和node02
    select * from mytbl;
    
5.2 双主双从
  1. node01、node02、node03、node04上各有一个mysql实例
  2. 其实就是主备模式,且为主和备各提供一个从机,目的是解决单点故障问题,平时主提供写的功能,从+备提供读的功能,当主宕机后,备提供写的功能,从+原主提供读的功能
  3. node01为主,node03为备,node02和node04为从
5.2.1 搭建
  1. node01:vi /etc/my.cnf

    server-id=1
    log-bin=mysql-bin
    binlog_format=STATEMENT
    #1. 当前库作为从库,同步了主库的binlog后,会将同步来数据也记入binlog
    #2. 如果不使用该参数,只是通过log-bin=mysql-bin开启binlog,那么只有直接向该库写入数据时,才会记录binlog,从主库同步来的数据是不会写binlog,这样,其他节点就无法以该库作为主库同步binlog
    #3. 虽然node01是主库,但他是有可能变为备库的,所以他本质上也会从其他库同步数据,因此也需要开启此参数
    log-slave-updates
    #1. 以下两个参数用于解决如果两个主都提供写的功能时,如果某字段为auto_increment,那么可能会导致的冲突问题
    #2. auto-increment-increment:每次递增的值,默认为1,取值范围可以从1~65535
    #3. auto-increment-offset:初始值,取值范围可以从1~65535
    #4. node01配置为auto-increment-offset=1,auto-increment-increment=2,表示字段值从1开始,每次递增2,因此就是1、3、5、7,node02上配置auto-increment-offset=2,auto-increment-increment=2,表示字段值从2开始,每次递增2,这样就是2、4、6、8,这样就不会产生冲突了
    auto-increment-increment=2
    auto-increment-offset=1
    
  2. node03:vi /etc/my.cnf

    server-id=3
    log-bin=mysql-bin
    binlog_format=STATEMENT
    log-slave-updates
    auto-increment-increment=2
    auto-increment-offset=2
    
  3. node02:vi /etc/my.cnf

    server-id=2
    #启用中继日志,日志名为mysql-relays
    relay-log=mysql-relay
    
  4. node04:vi /etc/my.cnf

    server-id=4
    relay-log=mysql-relay
    
  5. 所有节点重启mysql服务:service mysqld restart

  6. node01、node03:授予root用户replication slave权限

    grant replication slave on *.* to 'root'@'%' ;
    
  7. node01、node03:查看master状态,如果之前存在主从复制需要重置master

    reset master;
    show master status;
    
  8. node02、node04:指定master

    --node02
    CHANGE MASTER TO MASTER_HOST='192.168.246.128',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
    --node04
    CHANGE MASTER TO MASTER_HOST='192.168.246.130',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
    
  9. node02、node04:启动slave,并查看slave状态

    start slave;
    show slave status\G;
    
  10. node01跟node03相互复制

    --node01
    CHANGE MASTER TO MASTER_HOST='192.168.246.130',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
    start slave;
    show slave status\G;
    
    --node03
    CHANGE MASTER TO MASTER_HOST='192.168.246.128',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
    start slave;
    show slave status\G;
    
5.2.2 验证
  1. node01

    --都执行完毕后,到其他节点上是否同步成功
    create database msb;
    use msb;
    create table mytbl(id int,name varchar(20));
    insert into mytbl values(1,'zhangsan');
    
5.2.3 mycat配置读写分离
  1. schema.xml

    <!--
    	1. balance设置为1,表示一个writeHost提供写,剩下的writeHost和所有readHost提供读
    	2. writeType:配置到底哪个writeHost进行写
    		1. 0:所有写操作都默认发送到配置的第一个writeHost,如果第一个挂了,切换到第二个writeHost上,同时将写操作默认发送到的writeHost记录到dnindex.properties文件中
    		2. 1:所有写操作都随机的发送到配置的writehost中,1.5之后废弃
    	3. switchType:配置切换主备的方式
    		1. 1:默认值,表示自动切换
    		2. -1:表示不自动切换
    		3. 2:基于mysql主从同步的状态决定是否切换
    -->
    <dataHost name="host1" maxCon="1000" minCon="10" balance="1"
              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
      <heartbeat>select user()</heartbeat>
      <writeHost host="hostM1" url="192.168.246.128:3306" user="root" password="123456">
        <readHost host="hostS1" url="192.168.246.129:3306" user="root" password="123456"></readHost>
      </writeHost>
      <writeHost host="hostM2" url="192.168.246.130:3306" user="root" password="123456">
        <readHost host="hostS2" url="192.168.246.131:3306" user="root" password="123456"></readHost>
      </writeHost>
    </dataHost>
    
  2. 连接mycat并测试

    insert into mytbl values(4,@@hostname);
    --查询到的结果在node02,node03,node04之间切换
    select * from mytbl;
    --停止node01的mysql,恢复后重新插入语句
    insert into mytbl values(5,@@hostname);
    --查询到的结果在node01,node02,node04之间切换,说明node03已经变为了主,而node01变为了备,查看dnindex.properties文件,host1的值也由0变为了1
    select * from mytbl;
    
5.3 基于GTID的主从复制
5.3.1 简介
  1. GTID:Global Transaction ID,是Master上已提交事务在集群中的唯一编号,主从同步时,可以通过GTID确定slave节点当前同步到的位置,GTID使用master_auto_position=1代替了基于master_log_filemaster_log_pos的主从复制构建方式,强化了数据库的主从一致性、故障恢复及容错能力
  2. 在GTID出现以前,如果node01、node02互为主备,node03为node01的从机,那么一旦node01宕机,node02就应该作为新的主机,而node03应该改为从node02同步数据,但由于同一个事务在每台机器上所在的binlog名字和位置都不一样,我们很难找到node03当前同步停止点对应node02上的master_log_filemaster_log_pos,改为使用基于GTID的主从复制后,node03会根据自身的GTID自动找node02上该GTID之后的数据进行同步
  3. GTID = UUID+TID
    1. UUID:mysql实例的唯一标识
    2. TID:该实例上已经提交的事务数量,并且随着事务提交单调递增
5.3.2 搭建
  1. node01:主机,node02:从机

  2. node01、node02:vi /etc/my.cnf

    gtid_mode=on
    enforce-gtid-consistency=true
    
  3. node01、node02:重启服务service mysql restart

  4. node02:指定master

    stop slave;
    reset slave;
    change master to master_host='192.168.246.128',master_user='root',master_password='123456'
    ,master_auto_position=1;
    start slave;
    
  5. node01:插入数据测试

    create table test(id int,name varchar(10));
    insert into test values(1,'handidiao');
    insert into test values(2,'xuexiansheng');
    
  6. show slave status \G解析

    *************************** 1. row ***************************
    #1. io线程状态:所有master产生的事件都同步完毕,等master继续发送事件
                   Slave_IO_State: Waiting for master to send event
    #2. master的ip、用户、端口
                      Master_Host: 192.168.246.128
                      Master_User: root
                      Master_Port: 3306
    #3. 重连时间
                    Connect_Retry: 60
    #4. binlog名和当前位置,每执行一个dml语句,该值都变化
                  Master_Log_File: mysql-bin.000001
              Read_Master_Log_Pos: 795
    #5. relay log名和当前位置,每执行一个dml语句,该值都变化   
                   Relay_Log_File: mysql-relay.000002
                    Relay_Log_Pos: 1008
    #6. 当前机器产生的binlog名
            Relay_Master_Log_File: mysql-bin.000001
    #7. IO线程和SQL线程状态
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: 
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: 
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值